:root {
  --bg: #0f1115;
  --bg-elev: #1a1d24;
  --fg: #d9dde4;
  --fg-dim: #8b94a3;
  --accent: #5da7ff;
  --danger: #ff7676;
  --border: #2a2f3a;
  --sidebar-w: 280px;   /* annotation panel width — also the page push distance */
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  font-size: 14px;
  line-height: 1.5;
}

header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 24px;
  background: var(--bg-elev);
  border-bottom: 1px solid var(--border);
}

header h1 {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
}

/* Version chip next to the page title. Smaller and dimmer than the
   title — sits visually subordinate. Populated at startup by app.js
   via GET /api/health, so it always reflects the *daemon's* version
   (not whatever the static index.html was last served with). */
.version-tag {
  margin-left: 8px;
  padding: 1px 6px;
  font-size: 11px;
  font-weight: 500;
  color: var(--fg-dim);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 3px;
  font-variant-numeric: tabular-nums;
  vertical-align: middle;
}

main {
  padding: 24px;
  display: grid;
  grid-template-columns: 1fr;
  gap: 24px;
}

section h2 {
  margin: 0 0 12px 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--fg-dim);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

table {
  width: 100%;
  border-collapse: collapse;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
}

thead th {
  text-align: left;
  padding: 10px 12px;
  font-size: 12px;
  font-weight: 500;
  color: var(--fg-dim);
  background: rgba(255, 255, 255, 0.03);
  border-bottom: 1px solid var(--border);
}

tbody td {
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}

tbody tr:last-child td { border-bottom: 0; }

tbody tr:hover { background: rgba(255, 255, 255, 0.02); }

tbody td button {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--fg);
  padding: 3px 8px;
  border-radius: 3px;
  cursor: pointer;
  font-size: 12px;
  margin-right: 4px;
}

tbody td button:hover { background: var(--bg); }

/* Reading surface: the iframe IS the document. yzr-md-to-html ships
   a GitHub-dark palette (#0d1117 body), and that body itself is
   centered at max-width 880. The container's job is just to give it
   a *lifted* dark surface so the iframe border doesn't disappear into
   the chrome — and to keep the chrome from sprawling to ridiculous
   widths on 4K monitors. 1280 lets a 1366 laptop show the article
   + sidebar without horizontal scroll, while a 1920 monitor still
   caps the chrome's reach. The article's own 880 cap keeps line
   length comfortable inside. */
#preview-frame {
  display: block;
  width: 100%;
  max-width: 1280px;
  height: 78vh;
  margin: 0 auto;
  background: #1a1d24;        /* matches --bg-elev */
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.04) inset,
    0 8px 24px rgba(0, 0, 0, 0.35);
}

#toast {
  position: fixed;
  bottom: 24px;
  right: 24px;
  background: var(--bg-elev);
  color: var(--fg);
  border: 1px solid var(--border);
  padding: 10px 16px;
  border-radius: 6px;
  font-size: 13px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
}

code {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  background: var(--bg);
  padding: 1px 5px;
  border-radius: 3px;
}

.hint {
  font-size: 12px;
  color: var(--fg-dim);
}

/* Both modal dialogs (anno token + anno add) share a backdrop tone;
   collapse the two identical rules into one selector. */
dialog::backdrop { background: rgba(0, 0, 0, 0.4); }

/* --- file table ----------------------------------------------------------
   Row-level affordances: hover + cursor signal that the whole row is
   clickable; the tr has tabindex=0 so keyboard users get the same hint
   via focus ring (outline: revert picks the browser default focus
   outline, which respects OS high-contrast mode). */
#file-table tbody tr {
  cursor: pointer;
}
#file-table tbody tr:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

/* The parenthetical <title> next to a filename — dim, smaller, so the
   filename stays the visual anchor. */
.row-title {
  color: var(--fg-dim);
  font-size: 12px;
}

/* The "—" rendered for files with no annotations. */
.row-dim {
  color: var(--fg-dim);
}

/* The annotation-count link — accent-colored so it reads as actionable
   without competing with the filename link (which is also accent). */
.anno-count {
  color: var(--accent);
  text-decoration: none;
  font-variant-numeric: tabular-nums;
}
.anno-count:hover {
  text-decoration: underline;
}

/* Per-row action buttons (currently just "复制 URL"). Sits in its own
   column so it doesn't fight with row-click. */
.row-action {
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 3px 8px;
  font-size: 12px;
  cursor: pointer;
}
.row-action:hover {
  background: var(--bg-elev);
  border-color: var(--accent);
}
/* Destructive variant of the row-action button (anno-mode file delete).
   Text + border in --danger, no fill — signals danger without competing
   with the row's primary content or the red #load-error surface. */
.row-action.danger {
  color: var(--danger);
  border-color: var(--danger);
}
.row-action.danger:hover {
  background: rgba(255, 118, 118, 0.12);
  border-color: var(--danger);
}
/* The per-row delete button is always in the DOM but shown only in anno
   mode via body.anno-mode (toggled in setMode). Hidden by default so the
   page's default read mode stays read-only. */
.row-delete { display: none; }
body.anno-mode .row-delete { display: inline-block; }

/* Inline load-error card — visible in the table area when GET /api/files
   fails. Toast is for transient operations; this is for state. */
#load-error {
  padding: 16px 20px;
  border: 1px solid var(--danger);
  border-radius: 6px;
  background: rgba(255, 118, 118, 0.08);
  color: var(--fg);
  font-size: 13px;
}

/* --- annotation mode --- */
#anno-toggle {
  /* matches existing button styling */
  background: var(--accent);
  color: var(--bg);
  border: 0;
  border-radius: 4px;
  padding: 4px 12px;
  font-size: 13px;
  cursor: pointer;
}

#anno-toggle:hover { opacity: 0.85; }

#anno-mode-hint { color: var(--accent); }

#anno-token-dialog {
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 20px;
  min-width: 320px;
  background: var(--bg);
  color: var(--fg);
}

#anno-token-input {
  display: block;
  width: 100%;
  padding: 6px;
  margin: 8px 0;
  font-family: ui-monospace, monospace;
  font-size: 13px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--bg);
  color: var(--fg);
}

#anno-token-dialog menu {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin: 8px 0 0;
  padding: 0;
}

#anno-token-dialog button {
  padding: 4px 12px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--bg);
  color: var(--fg);
  cursor: pointer;
}

#anno-token-dialog button[type="submit"] {
  background: var(--accent);
  color: var(--bg);
  border-color: var(--accent);
}

#anno-token-dialog .error {
  color: var(--danger);
  margin-top: 8px;
  font-size: 12px;
}

#anno-sidebar {
  position: fixed;
  right: 0;
  top: 0;
  width: var(--sidebar-w);
  height: 100vh;
  background: var(--bg);
  border-left: 1px solid var(--border);
  padding: 12px;
  overflow-y: auto;
  font-size: 13px;
  transition: transform 0.2s ease;
}

/* Collapsed (user-folded OR nothing relevant to show): slide off-screen.
   pointer-events:none so the hidden panel never blocks clicks beneath it. */
#anno-sidebar.collapsed {
  transform: translateX(100%);
  pointer-events: none;
}

/* While the panel is open it PUSHES the page left instead of overlaying
   it. The panel is position:fixed at the right edge, full viewport height —
   a pure overlay covers everything living at that edge: the 大纲 toggle in
   .preview-head, the iframe's own scrollbar, and the header's action corner.
   (Regression in a804fea: anno mode forced the panel open AND hid the fold
   button, leaving no way to reach those controls.) margin-right animates
   in lockstep with the panel's 0.2s slide. */
header, main {
  transition: margin-right 0.2s ease;
}
body.anno-sidebar-open header,
body.anno-sidebar-open main {
  margin-right: var(--sidebar-w);
}
/* The toast is fixed at the right edge too — keep it clear of the panel. */
body.anno-sidebar-open #toast {
  right: calc(var(--sidebar-w) + 24px);
}

/* Header action cluster (refresh + collapse) replaces the lone refresh btn. */
.sidebar-actions {
  display: flex;
  gap: 4px;
}

#anno-collapse {
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 2px 8px;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
}
#anno-collapse:hover { background: var(--bg-elev); }

/* Thin vertical "批注" tab pinned to the right edge when the panel is
   folded — the only way back in once collapsed. */
#anno-opener {
  position: fixed;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  z-index: 15;
  writing-mode: vertical-rl;
  padding: 12px 4px;
  background: var(--bg-elev);
  color: var(--accent);
  border: 1px solid var(--border);
  border-right: 0;
  border-radius: 4px 0 0 4px;
  font-size: 13px;
  cursor: pointer;
}
#anno-opener:hover { background: var(--bg); }

#anno-sidebar header {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  /* Reset the global `header` rule (padding 12px 24px + bg-elev +
     border-bottom — that one is for the page's top bar). Here the header
     is just a thin row holding refresh + collapse at the panel's
     top-right; the sidebar's own 12px padding already insets it. Without
     this reset the buttons sat in a separate bg-elev bar that read as
     "outside" the list once the title was dropped. */
  padding: 0;
  margin: 0 0 8px 0;
  background: none;
  border: 0;
}

#anno-sidebar h3 { margin: 0; font-size: 14px; }

#anno-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

#anno-list li {
  padding: 8px;
  border: 1px solid var(--border);
  border-radius: 4px;
  margin-bottom: 8px;
}

#anno-list li .quote {
  font-style: italic;
  color: var(--fg-dim);
  font-size: 12px;
}

#anno-list li.invalid .quote::after {
  content: " ⚠️ 引用已变更";
  color: var(--danger);
}

#anno-list li .meta {
  font-size: 11px;
  color: var(--fg-dim);
  margin-top: 4px;
}

#anno-list li button {
  font-size: 11px;
  padding: 2px 6px;
  margin-right: 4px;
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: 3px;
  cursor: pointer;
}

#anno-list li button.danger {
  color: var(--danger);
  border-color: var(--danger);
}

/* --- annotation creation (F22: iframe selection → POST) --- */

/* Floating "＋ 批注" button, positioned over the preview iframe near the
   current selection. Lives in the parent document (iframe CSS can't reach
   it, per §9.3 iframe isolation); fixed-positioned in viewport coords. */
#anno-add-fab {
  position: fixed;
  z-index: 20;
  background: var(--accent);
  color: var(--bg);
  border: 0;
  border-radius: 4px;
  padding: 4px 10px;
  font-size: 12px;
  cursor: pointer;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
}

#anno-add-fab:hover { opacity: 0.85; }

#anno-add-dialog {
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 20px;
  min-width: 360px;
  max-width: 480px;
  background: var(--bg);
  color: var(--fg);
}

#anno-add-quote {
  margin: 8px 0;
  padding: 6px 10px;
  border-left: 3px solid var(--accent);
  font-style: italic;
  color: var(--fg-dim);
  font-size: 12px;
  max-height: 96px;
  overflow-y: auto;
  word-break: break-all;
}

#anno-add-truncated {
  margin: 4px 0;
  font-size: 12px;
  color: var(--danger);
}

#anno-add-comment {
  display: block;
  width: 100%;
  padding: 6px;
  margin: 8px 0;
  font-family: inherit;
  font-size: 13px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--bg);
  color: var(--fg);
  resize: vertical;
}

#anno-add-dialog menu {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin: 8px 0 0;
  padding: 0;
}

#anno-add-dialog button {
  padding: 4px 12px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--bg);
  color: var(--fg);
  cursor: pointer;
}

#anno-add-dialog button[type="submit"] {
  background: var(--accent);
  color: var(--bg);
  border-color: var(--accent);
}

#anno-add-dialog .error {
  color: var(--danger);
  margin-top: 8px;
  font-size: 12px;
}

/* File table — filename column renders as <a>; without this it falls back
   to the user-agent default (#0000EE in Chrome), which is unreadable on
   the dark --bg #0f1115. Use --accent (#5da7ff, ~8.4:1 on bg) instead. */
#file-table td a {
  color: var(--accent);
  text-decoration: none;
}
#file-table td a:hover {
  text-decoration: underline;
}

/* --- preview toolbar / iframe TOC (大纲) toggle ---
   Parent-side: the preview iframe is sandboxed without allow-scripts, so
   the md→html theme's own JS can't run there — the parent toggles its
   <aside class="sidebar"> directly. */
.preview-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
}
.preview-head h2 {
  margin: 0;
}

#toc-toggle {
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 3px 10px;
  font-size: 12px;
  cursor: pointer;
}
#toc-toggle:hover { background: var(--bg-elev); }
/* aria-pressed="true" = TOC currently hidden */
#toc-toggle[aria-pressed="true"] {
  background: var(--accent);
  color: var(--bg);
  border-color: var(--accent);
}
#toc-toggle:disabled {
  opacity: 0.4;
  cursor: default;
}

/* --- annotation popover (click a highlight to read its comment in place) ---
   The sidebar defaults to folded in read mode so it never covers the
   reading column; this popover is the primary way to read a comment. It
   lives in the parent doc and floats over the preview iframe. */
#anno-popover {
  position: fixed;
  z-index: 100000;
  max-width: 340px;
  min-width: 200px;
  background: var(--bg-elev);
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
  padding: 10px 30px 10px 12px;
  font-size: 13px;
  line-height: 1.45;
}
#anno-popover[hidden] { display: none; }
#anno-popover .ap-quote {
  color: var(--accent);
  font-style: italic;
  word-break: break-word;
}
#anno-popover .ap-comment {
  margin-top: 4px;
  white-space: pre-wrap;
  word-break: break-word;
}
#anno-popover .ap-meta {
  margin-top: 6px;
  color: var(--fg-dim);
  font-size: 11px;
}
#anno-popover .ap-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  margin-top: 8px;
  padding-top: 6px;
  border-top: 1px solid var(--border);
}
#anno-popover .ap-nav button {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--fg);
  border-radius: 4px;
  padding: 2px 8px;
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
}
#anno-popover .ap-nav button:hover {
  background: var(--bg);
  border-color: var(--accent);
}
#anno-popover .ap-counter {
  color: var(--fg-dim);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}
#anno-popover-close {
  position: absolute;
  top: 4px;
  right: 6px;
  background: transparent;
  border: none;
  color: var(--fg-dim);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  padding: 2px 4px;
}
#anno-popover-close:hover { color: var(--fg); }
