/* styles.css — Inkdrop-inspired three-pane theme with light/dark support.
   Variables drive theming; .theme-dark on <body> swaps the palette. */

/* Bundled UI/reading sans — Inter (SIL OFL, Google Fonts). The screen sans the
   modern note apps standardized on: Notion's default, Obsidian's interface font,
   Evernote's UI since 2024. A note app reads and writes prose, so it wants a
   clean neo-grotesque, not a newsprint serif or a code face. Latin subset,
   variable 400–700 (~48 KB); CJK falls through to the system sans (PingFang /
   YaHei) via --font-ui. This is the ONE face we ship. */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("fonts/inter-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ── June-flavor theme ───────────────────────────────────────────────────────
   Ported from open-software-network/os-june's tokens.css: OKLCH warm-neutral
   greys washed toward a clay terracotta accent and a warm-light sidebar (was a
   cool dark rail). Typography follows note-app convention (Notion/Obsidian/
   Evernote): clean Inter sans for UI, reading, and titles — no display serif. */
:root {
  --brand: #b5551f;          /* clay terracotta — June's --brand */
  --brand-wash: #976851;     /* chroma-capped companion; tints the neutrals */
  --accent: var(--brand);

  /* Warm neutral surfaces, stepping lightest→darkest: editor card, note list,
     sidebar ground. Each mixes a sliver of --brand-wash so the whole backdrop
     tints to the accent (June's surface-wash trick). */
  --editor-bg:   color-mix(in oklch, oklch(100% 0 none), var(--brand-wash) 2%);
  --list-bg:     color-mix(in oklch, oklch(96.5% 0.0015 84.59), var(--brand-wash) 3%);
  --list-border: color-mix(in oklch, oklch(86.91% 0.0015 84.59), var(--brand-wash) 5%);
  --list-hover:  color-mix(in oklch, oklch(92.87% 0.0015 84.59), var(--brand-wash) 4%);
  --chip-bg:     color-mix(in oklch, oklch(92.87% 0.0015 84.59), var(--brand-wash) 4%);
  --modal-bg:    color-mix(in oklch, oklch(100% 0 none), var(--brand-wash) 2%);
  --input-bg:    color-mix(in oklch, oklch(100% 0 none), var(--brand-wash) 2%);
  --text:        oklch(27.24% 0.0015 84.59);
  --text-muted:  oklch(55.8% 0.0015 84.59);
  /* Soft clay wash marks the active note (June's --brand-tint). */
  --selection:   color-mix(in oklch, var(--brand) 12%, var(--editor-bg));

  /* Warm-light sidebar (June's cream inset ground + near-black ink). */
  --sidebar-bg:        color-mix(in oklch, oklch(94% 0.0015 84.59), var(--brand-wash) 5%);
  --sidebar-fg:        oklch(27.24% 0.0015 84.59);
  --sidebar-muted:     oklch(55.8% 0.0015 84.59);
  --sidebar-active:    color-mix(in oklch, oklch(90% 0.0015 84.59), var(--brand-wash) 6%);
  --sidebar-fg-strong: oklch(20% 0.0015 84.59);                 /* was #fff */
  --sidebar-hover:     color-mix(in oklch, var(--brand-wash) 8%, transparent);
  --sidebar-border:    color-mix(in oklch, oklch(86.91% 0.0015 84.59), var(--brand-wash) 5%);
  --sidebar-icon-hover: color-mix(in oklch, var(--brand-wash) 13%, transparent);

  /* Primary sans: bundled Inter for Latin (consistent everywhere), then native
     fallbacks — Segoe UI Variable (Win11) / SF Pro (macOS) — and PingFang SC /
     YaHei so Chinese always has a clean sans. Used for UI, body, AND titles. */
  --font-ui: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI Variable Text", "Segoe UI", system-ui, "PingFang SC", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;
  /* Optional reading serif (not used by default) — Notion's "Serif" mode is
     Georgia; kept here should we add a per-note serif reading toggle later. */
  --font-serif: Georgia, "Iowan Old Style", "Songti SC", SimSun, "Times New Roman", serif;
  /* Mono for code spans/blocks: classic, widely-installed stack. */
  --font-mono: ui-monospace, "SFMono-Regular", "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;

  --status-active: #4a8f4d;
  --status-onHold: #c98a1a;
  --status-completed: var(--brand);
  --status-dropped: oklch(57% 0.15 30);
}

body.theme-dark {
  /* Warm charcoal port of June's dark sheet (warm-grey, never blue-black). */
  --editor-bg:   color-mix(in oklch, oklch(19.5% 0.0015 84.59), var(--brand-wash) 6%);
  --list-bg:     color-mix(in oklch, oklch(16.5% 0.0015 84.59), var(--brand-wash) 6%);
  --list-border: oklch(100% 0 0 / 10%);
  --list-hover:  color-mix(in oklch, oklch(26.8% 0.0015 84.59), var(--brand-wash) 7%);
  --chip-bg:     color-mix(in oklch, oklch(26.8% 0.0015 84.59), var(--brand-wash) 7%);
  --modal-bg:    color-mix(in oklch, oklch(19.5% 0.0015 84.59), var(--brand-wash) 6%);
  --input-bg:    color-mix(in oklch, oklch(26.8% 0.0015 84.59), var(--brand-wash) 7%);
  --text:        oklch(98.5% 0.0015 84.59);
  --text-muted:  oklch(70.9% 0.0015 84.59);
  --selection:   color-mix(in oklch, var(--brand) 30%, var(--editor-bg));

  --sidebar-bg:        color-mix(in oklch, oklch(14% 0.0015 84.59), var(--brand-wash) 6%);
  --sidebar-fg:        oklch(98.5% 0.0015 84.59);
  --sidebar-muted:     oklch(70.9% 0.0015 84.59);
  --sidebar-active:    color-mix(in oklch, oklch(22% 0.0015 84.59), var(--brand-wash) 7%);
  --sidebar-fg-strong: oklch(98.5% 0.0015 84.59);
  --sidebar-hover:     oklch(100% 0 0 / 6%);
  --sidebar-border:    oklch(100% 0 0 / 8%);
  --sidebar-icon-hover: oklch(100% 0 0 / 10%);
}

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
body {
  font-family: var(--font-ui);
  color: var(--text);
  background: var(--editor-bg);
  font-size: 14px;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow: hidden;
}

/* cross-platform scrollbars (WebKit/WebView2) */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: rgba(128, 128, 128, 0.35); border-radius: 5px; }
::-webkit-scrollbar-thumb:hover { background: rgba(128, 128, 128, 0.55); }
::-webkit-scrollbar-track { background: transparent; }

#app { display: grid; grid-template-columns: var(--col-sidebar, 232px) var(--col-notelist, 312px) 1fr; height: 100vh; position: relative; }
.col-resizer { position: absolute; top: 0; bottom: 0; width: 7px; margin-left: -3px;
  cursor: col-resize; z-index: 50; }
.col-resizer::after { content: ""; position: absolute; left: 3px; top: 0; bottom: 0; width: 1px; background: transparent; }
.col-resizer:hover::after, .col-resizer.dragging::after { background: var(--accent); }
/* sidebar toggled off (⌘S): collapse its column and hide its divider */
body.sidebar-collapsed #sidebar { display: none; }
body.sidebar-collapsed #resizer-1 { display: none; }
body.sidebar-collapsed #app { grid-template-columns: var(--col-notelist, 312px) 1fr; }

/* ---- sidebar ---------------------------------------------------------------- */
#sidebar { background: var(--sidebar-bg); color: var(--sidebar-fg); padding: 12px 10px; overflow: hidden; user-select: none; display: flex; flex-direction: column; }
.sidebar-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.sidebar-footer { flex: 0 0 auto; margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--sidebar-border); }
.sidebar-title { display: flex; justify-content: space-between; align-items: center; font-weight: 700; font-size: 15px; padding: 4px 6px 12px; color: var(--sidebar-fg-strong); }
/* Match the AI chat rail's wordmark (.ls-head h1): 19px / 600 / -0.02em.
   Truncate (don't push the buttons out) so the tight-width behaviour matches the
   chat rail: wordmark ellipsizes first, the flip pill never gets swallowed. */
.app-name { font-size: 19px; font-weight: 600; letter-spacing: -0.02em; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sidebar-title-actions { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }
/* Explicit Notes→Chat button — same fixed geometry (width/height/right inset) as
   the chat rail's "Notes" pill so the two pin exactly over each other on flip,
   but a violet "AI" tint (vs the rail's blue) so they're identifiable. */
.ai-chat-btn { display: inline-flex; align-items: center; justify-content: center; gap: 5px; flex: 0 0 auto; min-width: 100px; background: linear-gradient(135deg, color-mix(in oklch, var(--brand) 78%, white), var(--brand)); color: #fff; border: none; cursor: pointer; font-size: 12px; font-weight: 600; padding: 4px 10px; border-radius: 8px; line-height: 1.4; }
.ai-chat-btn:hover { filter: brightness(1.08); }
.sidebar-section { display: flex; justify-content: space-between; align-items: center; font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--sidebar-muted); padding: 14px 8px 5px; }
.nav-item, .tree-item { display: flex; align-items: center; gap: 7px; padding: 5px 8px; border-radius: 6px; cursor: pointer; white-space: nowrap; }
.nav-item:hover, .tree-item:hover { background: var(--sidebar-hover); }
.nav-item.active, .tree-item.active { background: var(--sidebar-active); color: var(--sidebar-fg-strong); }
.nav-icon, .tree-icon { width: 16px; display: inline-flex; align-items: center; justify-content: center; color: var(--sidebar-muted); }
/* Lucide inline icons: stroke = currentColor, so they take the tone of wherever
   they sit — muted in resting sidebar rows, lifted with the row text on
   hover/active, and correct in both themes with zero per-theme rules. */
.lucide { flex: none; display: block; }
.nav-item:hover .nav-icon, .nav-item.active .nav-icon,
.tree-item:hover .tree-icon, .tree-item.active .tree-icon { color: inherit; }
/* nested notebook tree: tighter spacing than nav rows so labels get more room */
.tree-item { gap: 2px; }
.tree-toggle { flex: 0 0 auto; width: 11px; text-align: right; font-size: 10px; line-height: 1; opacity: 0.8; color: var(--sidebar-muted); cursor: pointer; user-select: none; transition: opacity 0.1s, color 0.1s; }
.tree-toggle:hover { opacity: 1; color: var(--accent); }
.tree-toggle.empty { visibility: hidden; cursor: default; pointer-events: none; }
.nav-label, .tree-label { flex: 1; overflow: hidden; text-overflow: ellipsis; }
.nav-count { font-size: 11px; color: var(--sidebar-muted); min-width: 16px; text-align: right; }
.tree { list-style: none; margin: 0; padding: 0; }
.tag-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--accent); display: inline-block; }
.status-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; flex: 0 0 auto; }
.status-active { background: var(--status-active); }
.status-onHold { background: var(--status-onHold); }
.status-completed { background: var(--status-completed); }
.status-dropped { background: var(--status-dropped); }
.section-actions { display: flex; align-items: center; gap: 2px; }
#sort-books { font-size: 12px; font-weight: 600; }
.icon-btn { background: none; border: none; color: var(--sidebar-muted); cursor: pointer; font-size: 15px; line-height: 1; padding: 2px 6px; border-radius: 4px; }
.icon-btn:hover { background: var(--sidebar-icon-hover); color: var(--sidebar-fg-strong); }
.icon-btn:disabled { opacity: 0.28; cursor: default; pointer-events: none; }
/* Sidebar settings gear: square target + crisp SVG, sized/colored to match the
   chat rail's gear (.ls-ico) so the two left bars read identically. Brighter than
   --sidebar-muted so it's an obvious, findable control next to the AI Chat pill. */
/* Bottom-left "Settings" row — shared by the Notes sidebar (#settings-btn) and
   the chat rail (.ls-settings), so both panels look the same. */
.settings-row { display: flex; align-items: center; gap: 9px; width: 100%; padding: 8px; border: none; background: none; cursor: pointer; border-radius: 6px; color: var(--sidebar-fg); font-size: 13px; font-family: inherit; }
.settings-row:hover { background: var(--sidebar-icon-hover); color: var(--sidebar-fg-strong); }
.settings-row svg { display: block; flex: 0 0 auto; }

/* ---- note list -------------------------------------------------------------- */
#note-list-pane { background: var(--list-bg); border-right: 1px solid var(--list-border); display: flex; flex-direction: column; overflow: hidden; }
.list-toolbar { display: flex; gap: 8px; padding: 12px; border-bottom: 1px solid var(--list-border); position: relative; z-index: 60; }
.search { flex: 1; min-width: 0; border: 1px solid var(--list-border); border-radius: 8px; padding: 6px 10px; font-size: 13px; background: var(--input-bg); color: var(--text); }
.search:focus { outline: none; border-color: var(--accent); }
.primary-btn { background: var(--accent); color: #fff; border: none; border-radius: 8px; padding: 6px 12px; cursor: pointer; font-weight: 600; white-space: nowrap; }
.primary-btn:hover { filter: brightness(1.06); }
.list-subbar { display: flex; justify-content: space-between; align-items: center; padding: 8px 14px 4px; }
.list-title { font-size: 12px; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.03em; }
.mini-select { font-size: 11px; border: 1px solid var(--list-border); border-radius: 5px; background: var(--input-bg); color: var(--text-muted); padding: 2px 4px; }
.note-list { list-style: none; margin: 0; padding: 0; overflow-y: auto; flex: 1; }
/* Fixed 78px row height keeps the list tidy and keyboard scroll math simple. */
.note-item { height: 78px; box-sizing: border-box; padding: 9px 14px; border-bottom: 1px solid var(--list-border); cursor: pointer; overflow: hidden; }
/* Remote (Web) virtualization: off-screen spacer <li>s reserve scroll height; skeleton
   rows stand in for not-yet-fetched notes so a fast scroll never shows a blank, and the
   placeholder is unclickable (pointer-events:none) so it's never a dead click target. */
.note-vspacer { list-style: none; padding: 0; margin: 0; }
.note-skeleton { cursor: default; pointer-events: none; display: flex; flex-direction: column; justify-content: center; gap: 8px; }
.note-skeleton .skel-bar { height: 11px; border-radius: 4px; background: linear-gradient(90deg, var(--list-border) 25%, var(--list-hover) 37%, var(--list-border) 63%); background-size: 400% 100%; animation: skel-shimmer 1.4s ease infinite; }
.note-skeleton .skel-title { width: 62%; }
.note-skeleton .skel-snip { width: 88%; height: 9px; }
@keyframes skel-shimmer { 0% { background-position: 100% 0; } 100% { background-position: -100% 0; } }
/* Conflicts list items + the side-by-side diff modal */
/* Conflict rows carry two action buttons, so they can't use the fixed 78px note-row
   height — let them grow so a wrapped "Keep incoming" sits on its own row, not clipped. */
.note-item.conflict-item { height: auto; overflow: visible; }
.conflict-item .conflict-acts { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
/* keep full labels readable: never break "Keep yours" mid-word; when the column is
   too narrow for both buttons side-by-side, the second wraps onto its own row. */
.conflict-item .conflict-acts .conflict-btn { flex: 1 1 auto; white-space: nowrap; text-align: center; }
.conflict-btn { padding: 5px 10px; border: 1px solid var(--list-border); border-radius: 6px; background: var(--list-bg); color: var(--text); cursor: pointer; font-size: 12px; }
.conflict-btn.mine { border-color: var(--accent); color: var(--accent); font-weight: 600; }
.conflict-btn:hover { background: var(--list-hover); }
/* conflict detail — fills the editor pane (right column) */
#conflict-detail { position: absolute; inset: 0; z-index: 6; background: var(--editor-bg); display: flex; flex-direction: column; overflow: hidden; }
#conflict-detail.hidden { display: none; } /* id+class beats the #conflict-detail display:flex above */
.cd-head { padding: 14px 16px 10px; border-bottom: 1px solid var(--list-border); }
.cd-title { font-weight: 700; font-size: 16px; }
.cd-sub { font-size: 12px; color: var(--text-muted); margin-top: 3px; }
.cd-meta { display: flex; gap: 10px; padding: 12px 16px; border-bottom: 1px solid var(--list-border); }
.cd-col { flex: 1; min-width: 0; border: 1px solid var(--list-border); border-radius: 8px; padding: 10px 12px; }
.cd-col.mine { border-color: var(--accent); }
.cd-col-label { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-muted); margin-bottom: 8px; }
.cd-row { display: flex; gap: 8px; font-size: 12.5px; padding: 2px 0; }
.cd-k { color: var(--text-muted); min-width: 72px; flex: 0 0 72px; }
.cd-v { color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cd-open { display: inline-flex; align-items: center; gap: 5px; margin-top: 10px; padding: 5px 10px;
  font-size: 12px; color: var(--text); background: var(--list-bg); border: 1px solid var(--list-border);
  border-radius: 6px; cursor: pointer; transition: border-color 0.12s, color 0.12s; }
.cd-open:hover { border-color: var(--accent); color: var(--accent); }
.cd-col.mine .cd-open:hover { border-color: var(--accent); }
.cd-merge { flex: 1; min-height: 0; overflow: auto; }
.cd-merge .cm-mergeView, .cd-merge .cm-editor { height: auto; }
.cd-acts { display: flex; gap: 8px; justify-content: flex-end; padding: 12px 16px; border-top: 1px solid var(--list-border); }
.cd-acts .conflict-btn { padding: 8px 18px; font-size: 13px; }
.note-item:hover { background: var(--list-hover); }
.note-item.active { background: var(--selection); box-shadow: inset 3px 0 0 var(--accent); }
.note-item-top { display: flex; align-items: center; gap: 6px; }
.note-item-title { font-weight: 600; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.note-pin { font-size: 10px; flex: 0 0 auto; background: var(--accent); border-radius: 8px;
  padding: 1px 5px; line-height: 1.5; }
/* a faint accent bar marks pinned items at a glance (unless already selected) */
.note-item.pinned:not(.active):not(.multi-selected) { box-shadow: inset 3px 0 0 color-mix(in oklch, var(--brand) 55%, transparent); }
.note-item-snippet { color: var(--text-muted); font-size: 12px; margin-top: 3px; height: 16px; overflow: hidden; }
.note-item-meta { display: flex; gap: 8px; margin-top: 4px; }
.note-item-date { color: var(--text-muted); opacity: 0.8; font-size: 11px; }
.note-item-tags { color: var(--accent); font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.list-empty { padding: 20px 14px; color: var(--text-muted); }
.note-item mark { background: #ffe58a; color: inherit; border-radius: 2px; padding: 0 1px; }
body.theme-dark .note-item mark { background: #7a6620; color: #fff; }

.keymap-keys kbd { background: var(--chip-bg); border: 1px solid var(--list-border); border-bottom-width: 2px; border-radius: 4px; padding: 1px 6px; font-family: var(--font-mono); font-size: 11px; margin-left: 4px; }
.task-badge { font-size: 10px; background: var(--chip-bg); color: var(--text-muted); border-radius: 8px; padding: 1px 6px; white-space: nowrap; flex: 0 0 auto; }
.task-badge.done { background: rgba(33, 186, 69, 0.16); color: var(--status-active); }

/* GFM task lists in preview (micromark output, made clickable) */
.markdown-body li.task-item { list-style: none; display: flex; align-items: flex-start; gap: 8px; margin: 3px 0; margin-left: -1.1em; }
.markdown-body .task-checkbox { margin-top: 4px; cursor: pointer; accent-color: var(--accent); }
/* GFM tables */
.markdown-body table { border-collapse: collapse; margin: 0.7em 0; font-size: 0.95em; }
.markdown-body th, .markdown-body td { border: 1px solid var(--list-border); padding: 5px 10px; text-align: left; }
.markdown-body th { background: var(--chip-bg); font-weight: 600; }
.markdown-body del { opacity: 0.6; }
.markdown-body .footnotes { margin-top: 1.4em; padding-top: 0.6em; border-top: 1px solid var(--list-border);
  font-size: 0.88em; color: var(--text-muted); }
.markdown-body .footnotes ol { padding-left: 1.4em; }
.markdown-body [data-footnote-ref] { font-size: 0.8em; padding: 0 1px; }
.markdown-body .footnote-backref { text-decoration: none; margin-left: 4px; }
.markdown-body .katex-display { overflow-x: auto; overflow-y: hidden; padding: 2px 0; }
.markdown-body .math-error { color: #c0392b; background: rgba(192,57,43,0.08); }
.markdown-body .mermaid-diagram { margin: 0.8em 0; text-align: center; overflow-x: auto; }
.markdown-body .mermaid-diagram svg { max-width: 100%; height: auto; }
.markdown-body .mermaid-error { color: #c0392b; background: rgba(192,57,43,0.08); white-space: pre-wrap; }

/* ---- editor ----------------------------------------------------------------- */
#editor-pane { background: var(--editor-bg); display: flex; flex-direction: column; position: relative; overflow: hidden; }
/* flex-wrap lets the tool icons drop to a second row instead of overflowing the
   pane's right edge (where #editor-pane{overflow:hidden} would clip them) once the
   window/pane gets narrow. Verified across widths with _uitest/resize.mjs. */
#editor-header { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 9px 14px; border-bottom: 1px solid var(--list-border); }
.drag-handle { cursor: grab; color: var(--text-muted); font-size: 14px; user-select: none; padding: 2px 4px; border-radius: 4px; flex: 0 0 auto; }
.drag-handle:hover { background: var(--list-hover); color: var(--text); }
.drag-handle:active { cursor: grabbing; }
.date-info { flex: 0 0 auto; color: var(--text-muted); font-size: 11px; white-space: nowrap; padding-left: 8px; }
/* min-width:0 lets the title fully yield so the toolbar stays on row 1 as long as it
   fits, and only wraps to row 2 when genuinely out of room (not prematurely). */
.title-input { flex: 1; min-width: 0; border: none; background: none; font-family: var(--font-ui); font-size: 22px; font-weight: 700; letter-spacing: -0.02em; padding: 4px 0; color: var(--text); }
.title-input:focus { outline: none; }
/* flex-shrink:0 keeps each icon full-size (the title yields, not the toolbar);
   max-width:100% caps the group to the row width so its own flex-wrap kicks in and the
   icons wrap across rows instead of overflowing the pane; margin-left:auto right-aligns
   the group, including when it wraps onto its own row. */
.editor-actions { display: flex; gap: 4px; align-items: center; flex-shrink: 0; flex-wrap: wrap; justify-content: flex-end; margin-left: auto; max-width: 100%; }
.outline-panel {
  position: absolute; top: 48px; right: 12px; z-index: 40;
  width: 240px; max-height: 60%; overflow-y: auto;
  background: var(--editor-bg); border: 1px solid var(--list-border);
  border-radius: 8px; box-shadow: 0 8px 28px rgba(0,0,0,0.18);
  padding: 6px 0; font-size: 13px;
}
.outline-panel.hidden { display: none; }
.outline-item { padding: 4px 12px; cursor: pointer; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.outline-item:hover { background: var(--list-hover); }
.outline-item.active { background: var(--accent); color: #fff; }
.outline-item.active.outline-h4, .outline-item.active.outline-h5, .outline-item.active.outline-h6 { color: #fff; }
.outline-h1 { font-weight: 600; }
.outline-h2 { padding-left: 22px; }
.outline-h3 { padding-left: 32px; }
.outline-h4 { padding-left: 42px; color: var(--text-muted); }
.outline-h5, .outline-h6 { padding-left: 52px; color: var(--text-muted); }
.outline-empty { padding: 8px 12px; color: var(--text-muted); }
.ac-menu {
  position: fixed; z-index: 60; min-width: 180px; max-width: 320px; max-height: 220px;
  overflow-y: auto; background: var(--editor-bg); border: 1px solid var(--list-border);
  border-radius: 8px; box-shadow: 0 8px 28px rgba(0,0,0,0.18); padding: 4px 0; font-size: 13px;
}
.ac-item { display: flex; align-items: baseline; gap: 10px; padding: 5px 12px; cursor: pointer;
  color: var(--text); }
.ac-label { flex: 1 1 auto; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ac-hint { flex: 0 0 auto; font-size: 11px; color: var(--text-muted); font-family: var(--mono, monospace); }
.ac-item.active, .ac-item:hover { background: var(--accent); color: #fff; }
.ac-item.active .ac-hint, .ac-item:hover .ac-hint { color: rgba(255,255,255,0.7); }
.greplace-modal .modal-input { display: block; width: 100%; margin: 8px 0; }
.greplace-case { display: flex; align-items: center; gap: 6px; font-size: 13px;
  color: var(--text-muted); margin: 4px 0 2px; cursor: pointer; }
.storage-pane .setting-label { display: block; font-weight: 600; margin: 14px 0 6px; }
.storage-path-row { display: flex; align-items: center; gap: 8px; }
.storage-path { flex: 1; overflow-x: auto; white-space: nowrap; background: var(--chip-bg);
  border: 1px solid var(--list-border); border-radius: 6px; padding: 5px 8px; font-size: 12px; }
.storage-path-actions { display: flex; gap: 6px; flex-shrink: 0; }
.storage-path-actions .ghost-btn { padding: 4px 10px; font-size: 12px; }
.backlinks { border-top: 1px solid var(--list-border); padding: 8px 14px; max-height: 22%;
  overflow-y: auto; background: var(--editor-bg); flex-shrink: 0; }
.backlinks.hidden { display: none; }
.backlinks-title { font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--text-muted); margin-bottom: 5px; }
.backlinks-item { padding: 3px 6px; border-radius: 5px; cursor: pointer; font-size: 13px;
  color: var(--accent); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.backlinks-item:hover { background: var(--list-hover); }
/* history mode: banner + revisions side panel (content shows in the real editor) */
.history-bar { display: none; align-items: center; justify-content: space-between;
  gap: 10px; padding: 7px 14px; background: var(--chip-bg);
  border-bottom: 1px solid var(--list-border); font-size: 13px; color: var(--text); }
.history-bar-actions { display: flex; gap: 8px; }
.history-bar .primary-btn, .history-bar .ghost-btn { padding: 4px 12px; font-size: 12px; }
.history-panel { position: absolute; top: 48px; right: 12px; z-index: 45;
  width: 250px; max-height: 70%; overflow-y: auto; background: var(--editor-bg);
  border: 1px solid var(--list-border); border-radius: 8px;
  box-shadow: 0 8px 28px rgba(0,0,0,0.18); padding: 4px 0; }
.history-panel.hidden { display: none; }
.history-panel-title { font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--text-muted); padding: 8px 12px 4px; }
.history-item { padding: 7px 12px; cursor: pointer; border-top: 1px solid var(--list-border); }
.history-item:hover { background: var(--list-hover); }
.history-item.active { background: var(--accent); }
.history-item.active .history-when, .history-item.active .history-meta { color: #fff; }
.history-current { border-bottom: 1px solid var(--list-border); }
.history-current .history-meta { color: var(--accent); }
.history-when { font-size: 13px; color: var(--text); }
.history-meta { font-size: 11px; color: var(--text-muted); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
#editor-pane .icon-btn { color: var(--text-muted); }
#editor-pane .icon-btn:hover { background: var(--list-hover); color: var(--text); }
#editor-pane .icon-btn.active { color: var(--accent); }
/* pinned: fill the button so state is obvious (emoji ignore text color) */
#pin-btn.active { background: var(--accent); border-radius: 6px; }
#pin-btn.active:hover { background: var(--accent); }
/* flex-wrap + max-width let the segmented control wrap its buttons within the group
   once the pane is narrower than the three buttons side by side — otherwise the group
   is one unshrinkable flex item that overflows the pane's right edge and gets clipped
   by #editor-pane{overflow:hidden}. Verified with _uitest/resize.mjs down to 640px. */
.viewmode-group { display: flex; flex-wrap: wrap; max-width: 100%; border: 1px solid var(--list-border); border-radius: 6px; overflow: hidden; margin-right: 4px; }
.vm-btn { background: none; border: none; padding: 4px 8px; cursor: pointer; color: var(--text-muted); font-size: 12px; }
.vm-btn:hover { background: var(--list-hover); }
.vm-btn.active { background: var(--accent); color: #fff; }

#editor-meta { display: flex; align-items: center; gap: 8px; padding: 7px 14px; border-bottom: 1px solid var(--list-border); flex-wrap: wrap; }
.meta-select { border: 1px solid var(--list-border); border-radius: 6px; padding: 3px 6px; font-size: 12px; background: var(--input-bg); color: var(--text); }
.tag-editor { display: flex; align-items: center; gap: 5px; flex: 1; flex-wrap: wrap; position: relative; }
.tag-suggest { position: absolute; top: 100%; left: 0; margin-top: 4px; min-width: 180px; max-height: 220px; overflow-y: auto; background: var(--modal-bg); border: 1px solid var(--list-border); border-radius: 6px; box-shadow: 0 6px 20px rgba(0,0,0,0.2); z-index: 60; }
.tag-suggest-item { display: flex; justify-content: space-between; gap: 12px; padding: 6px 10px; cursor: pointer; font-size: 12px; color: var(--accent); }
.tag-suggest-item:hover, .tag-suggest-item.active { background: var(--accent); color: #fff; }
.tag-suggest-item.active .tag-suggest-count, .tag-suggest-item:hover .tag-suggest-count { color: #fff; }
.tag-suggest-count { color: var(--text-muted); }
.tag-chips { display: flex; gap: 5px; flex-wrap: wrap; }
.tag-chip { background: var(--chip-bg); color: var(--accent); border-radius: 10px; padding: 2px 8px; font-size: 11px; display: inline-flex; align-items: center; gap: 4px; }
.tag-chip-x { background: none; border: none; color: var(--text-muted); cursor: pointer; font-size: 13px; line-height: 1; padding: 0; }
.tag-chip-x:hover { color: var(--status-dropped); }
.tag-input { border: none; background: none; font-size: 12px; color: var(--text); min-width: 60px; }
.tag-input:focus { outline: none; }

.trash-bar { display: none; align-items: center; gap: 10px; padding: 8px 14px; background: rgba(219, 40, 40, 0.08); color: var(--text-muted); font-size: 12px; border-bottom: 1px solid var(--list-border); }

#editor-body { flex: 1; display: grid; overflow: hidden; }
#editor-body.mode-side { grid-template-columns: 1fr 1fr; }
#editor-body.mode-editor, #editor-body.mode-live { grid-template-columns: 1fr 0; }
/* read-only Live preview: the rendered preview pane full-width (editor hidden) */
#editor-body.mode-preview { grid-template-columns: 0 1fr; }
.cm-host { overflow: hidden; border-right: 1px solid var(--list-border); }
#editor-body.mode-editor .cm-host, #editor-body.mode-live .cm-host { border-right: none; }
.cm-host .CodeMirror { height: 100%; font-family: var(--font-mono); font-size: inherit; background: var(--editor-bg); color: var(--text); padding: 6px 8px; }
body.theme-dark .cm-host .CodeMirror { color: var(--text); }
body.theme-dark .CodeMirror-cursor { border-left-color: var(--text); }
body.theme-dark .CodeMirror-selected { background: var(--selection) !important; }
body.theme-dark .CodeMirror-gutters { background: var(--editor-bg); border-right: 1px solid var(--list-border); }
body.theme-dark .CodeMirror-linenumber { color: var(--text-muted); }

/* CodeMirror 6 (cm6-bundle) — the new engine. Mirrors the CM5 rules above using
   the same variables, so light/dark and the editor chrome match. The adapter adds
   the .CodeMirror class to .cm-editor, so container rules above still apply. */
.cm-host .cm-editor { height: 100%; background: var(--editor-bg); }
.cm-host .cm-editor.cm-focused { outline: none; }
/* File drag-and-drop target cue (see handleEditorDragOver in app.js). */
.cm-host .cm-editor.cm-drop-active { outline: 2px dashed var(--accent); outline-offset: -3px; background: var(--selection); }
.cm-host .cm-scroller { font-family: var(--font-mono); font-size: inherit; line-height: 1.5; }
.cm-host .cm-content { padding: 6px 8px; color: var(--text); caret-color: var(--text); }
.cm-host .cm-line { padding: 0; }
.cm-host .cm-gutters { background: var(--editor-bg); border: none; color: var(--text-muted); }
.cm-host .cm-activeLineGutter, .cm-host .cm-activeLine { background: transparent; }
.cm-cursor, .cm-dropCursor { border-left-color: var(--text); }
.cm-selectionBackground, .cm-focused .cm-selectionBackground,
.cm-content ::selection { background: var(--selection) !important; }
.cm-host .cm-placeholder { color: var(--text-muted); }
/* in-editor find/replace panel (CM6 @codemirror/search) — custom VSCode-style
   panel built in frontend/editor/cm6.js (SearchPanel): a live match counter, and
   compact icon option-toggles (Aa / ab / .*) tucked inside the find field. */
.cm-panels { background: var(--editor-bg); color: var(--text); border-bottom: 1px solid var(--list-border); }
/* CM6's base theme parks the find/replace panel at z-index:300, which covers the
   app's own context menus (200), AI menu, and outline/history panels. It only needs
   to sit above the editor text (z-index:0) — pin it low. Two-class selector to beat
   CM6's single-class `.cm-panels` rule regardless of stylesheet order. */
.cm-editor .cm-panels { z-index: 5; }
.cm-panels.cm-panels-bottom { border-top: 1px solid var(--list-border); border-bottom: none; }
.cm-panel.cm-search { display: flex; align-items: flex-start; gap: 8px; padding: 8px 10px; font-size: 12px; }
.cm-panel.cm-search .cm-search-fields { display: flex; flex-direction: column; gap: 6px; flex: 1; min-width: 0; }
.cm-panel.cm-search .cm-search-row { display: flex; align-items: center; gap: 6px; }
.cm-panel.cm-search input, .cm-panel.cm-search button {
  font-size: 12px; color: var(--text); vertical-align: middle; margin: 0; box-sizing: border-box; }

/* the text field + its inline toggles share one bordered "input" shell */
.cm-panel.cm-search .cm-search-input {
  position: relative; display: flex; align-items: center;
  flex: 0 1 280px; min-width: 160px; max-width: 340px;
  background: var(--input-bg); border: 1px solid var(--list-border); border-radius: 6px; }
.cm-panel.cm-search .cm-search-input:focus-within { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.cm-panel.cm-search .cm-textfield {
  flex: 1; min-width: 0; background: transparent; color: var(--text);
  border: none; outline: none; padding: 4px 8px; height: 26px; }
.cm-panel.cm-search .cm-search-input:has(.cm-search-toggles) .cm-textfield { padding-right: 2px; }

/* inline Aa / ab / .* toggle buttons */
.cm-panel.cm-search .cm-search-toggles { display: flex; align-items: center; gap: 2px; padding: 0 3px; }
.cm-panel.cm-search .cm-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 22px; height: 20px; padding: 0 4px; border: none; border-radius: 4px;
  background: transparent; color: var(--text-muted); font-size: 11px; line-height: 1;
  font-family: var(--font-mono, ui-monospace, monospace); cursor: pointer; }
.cm-panel.cm-search .cm-toggle:hover { background: var(--list-hover); color: var(--text); }
.cm-panel.cm-search .cm-toggle[aria-pressed="true"] {
  background: color-mix(in srgb, var(--accent) 22%, transparent); color: var(--accent); }
.cm-panel.cm-search .cm-toggle[name="word"] { text-decoration: underline; text-underline-offset: 2px; }

/* live "N of M" / "No results" counter beside the find field */
.cm-panel.cm-search .cm-search-count {
  min-width: 58px; color: var(--text-muted); font-variant-numeric: tabular-nums;
  white-space: nowrap; }
.cm-panel.cm-search .cm-search-count-none { color: var(--danger, #e5534b); }

/* action buttons (Replace / All) */
.cm-panel.cm-search .cm-button {
  background: var(--list-hover); border: 1px solid var(--list-border); border-radius: 6px;
  padding: 4px 10px; height: 26px; cursor: pointer; line-height: 1; background-image: none; }
.cm-panel.cm-search .cm-button:hover { background: var(--chip-bg); }
/* prev/next arrow buttons — compact squares */
.cm-panel.cm-search button[name="prev"], .cm-panel.cm-search button[name="next"] {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; padding: 0; font-size: 13px; }
/* close (×) — borderless, aligned to the first row */
.cm-panel.cm-search button[name="close"] {
  flex: none; align-self: flex-start; width: 26px; height: 26px;
  background: none; border: none; border-radius: 6px; font-size: 16px; line-height: 1;
  color: var(--text-muted); cursor: pointer; }
.cm-panel.cm-search button[name="close"]:hover { background: var(--list-hover); color: var(--text); }

.cm-searchMatch { background: rgba(255, 200, 0, 0.32); }
.cm-searchMatch-selected { background: color-mix(in srgb, var(--accent) 30%, transparent); }
/* Live Preview (decoration WYSIWYG) — frontend/editor/live-preview.js */
.cm-host .cm-lp-strong { font-weight: 700; }
.cm-host .cm-lp-em { font-style: italic; }
.cm-host .cm-lp-strike { text-decoration: line-through; color: var(--text-muted); }
.cm-host .cm-lp-code { font-family: var(--font-mono); background: var(--chip-bg); border-radius: 4px; padding: 0 3px; }
.cm-host .cm-line.cm-lp-h1 { font-size: 1.6em; font-weight: 700; line-height: 1.3; }
.cm-host .cm-line.cm-lp-h2 { font-size: 1.35em; font-weight: 700; line-height: 1.3; }
.cm-host .cm-line.cm-lp-h3 { font-size: 1.2em; font-weight: 700; }
.cm-host .cm-line.cm-lp-h4 { font-size: 1.08em; font-weight: 700; }
.cm-host .cm-line.cm-lp-h5, .cm-host .cm-line.cm-lp-h6 { font-weight: 700; color: var(--text-muted); }
.cm-host input.cm-lp-task { vertical-align: middle; margin: 0 4px 0 0; cursor: pointer; accent-color: var(--accent); }
.cm-host .cm-lp-link { color: var(--accent); text-decoration: none; }
.cm-host .cm-line.cm-lp-quote { border-left: 3px solid var(--list-border); padding-left: 10px; color: var(--text-muted); }
.cm-host .cm-lp-bullet { color: var(--text-muted); }
.cm-host .cm-lp-hr { display: inline-block; width: 100%; border-top: 1px solid var(--list-border); vertical-align: middle; }
.cm-host img.cm-lp-img { max-width: 100%; display: block; margin: 4px 0; border-radius: 6px; }
/* GFM tables — rendered inline, matching the preview pane */
.cm-host .cm-lp-table { margin: 6px 0; overflow-x: auto; }
.cm-host .cm-lp-table table { border-collapse: collapse; }
.cm-host .cm-lp-table th, .cm-host .cm-lp-table td { border: 1px solid var(--list-border); padding: 4px 10px; }
.cm-host .cm-lp-table th { background: var(--chip-bg); font-weight: 700; }
/* KaTeX math */
.cm-host .cm-lp-math-display { display: block; text-align: center; margin: 6px 0; }
/* alert callouts (> [!NOTE] …) — left bar + tint per type, matches the preview */
.cm-host .cm-line.cm-lp-alert { padding-left: 12px; border-left: 3px solid var(--list-border); }
.cm-host .cm-line.cm-lp-alert-note { border-left-color: #2185d0; background: rgba(33, 133, 208, 0.06); }
.cm-host .cm-line.cm-lp-alert-tip { border-left-color: #21ba45; background: rgba(33, 186, 69, 0.06); }
.cm-host .cm-line.cm-lp-alert-important { border-left-color: #a333c8; background: rgba(163, 51, 200, 0.06); }
.cm-host .cm-line.cm-lp-alert-warning { border-left-color: #fbbd08; background: rgba(251, 189, 8, 0.08); }
.cm-host .cm-line.cm-lp-alert-caution { border-left-color: #db2828; background: rgba(219, 40, 40, 0.06); }
.cm-host .cm-lp-alert-title { font-weight: 700; }
/* fenced code blocks — a monospace box; ``` fences dimmed */
.cm-host .cm-line.cm-lp-codeblock { background: var(--chip-bg); font-family: var(--font-mono); }
.cm-host .cm-lp-fence { color: var(--text-muted); opacity: 0.6; }
.cm-host .cm-lp-fence-info { color: var(--text-muted); font-style: italic; }

/* search-palette preview instance on CM6 */
.velocity-preview-pane .cm-editor { height: 100%; background: transparent; font-size: 13px; color: var(--text); }
.velocity-preview-pane .cm-content { padding: 8px 10px; }

.markdown-body { padding: 16px 22px; overflow-y: auto; line-height: 1.65; color: var(--text); }
.markdown-body h1, .markdown-body h2, .markdown-body h3 { margin: 0.6em 0 0.3em; line-height: 1.3; }
.markdown-body h1 { font-weight: 700; letter-spacing: -0.02em; font-size: 1.7em; border-bottom: 1px solid var(--list-border); padding-bottom: 0.2em; }
.markdown-body h2 { font-size: 1.3em; }
.markdown-body p { margin: 0.5em 0; }
.markdown-body code { background: var(--chip-bg); padding: 1px 5px; border-radius: 4px; font-family: var(--font-mono); font-size: 0.9em; }
.markdown-body pre { background: var(--chip-bg); padding: 12px 14px; border-radius: 8px; overflow-x: auto; }
.markdown-body pre code { background: none; padding: 0; }
.markdown-body blockquote { margin: 0.5em 0; padding: 0.2em 1em; border-left: 3px solid var(--list-border); color: var(--text-muted); }
.markdown-body ul, .markdown-body ol { padding-left: 1.4em; }
.markdown-body a { color: var(--accent); text-decoration: none; }
.markdown-body a:hover { text-decoration: underline; }
.markdown-body hr { border: none; border-top: 1px solid var(--list-border); margin: 1em 0; }

.status-bar { display: flex; justify-content: space-between; padding: 5px 14px; border-top: 1px solid var(--list-border); font-size: 11px; color: var(--text-muted); }

/* formatting toolbar */
.editor-toolbar { display: flex; align-items: center; gap: 5px 0; padding: 5px 10px; border-bottom: 1px solid var(--list-border); flex-wrap: wrap; }
/* a section of buttons that stays together — wraps to the next line as a unit.
   The separator is a left border on the group, so it travels with the section
   when it wraps instead of dangling at a line end like a standalone divider. */
.tb-group { display: flex; align-items: center; gap: 2px; flex: 0 0 auto; margin-left: 6px; padding-left: 8px; border-left: 1px solid var(--list-border); }
.tb-group:first-child { margin-left: 0; padding-left: 0; border-left: none; }
.tb-btn { background: none; border: none; cursor: pointer; color: var(--text-muted); font-size: 13px; min-width: 28px; height: 26px; border-radius: 5px; padding: 0 7px; }
.tb-btn:hover { background: var(--list-hover); color: var(--text); }

/* single-note window (opened via ?note=ID) */
body.single-note #app { grid-template-columns: 1fr; }
body.single-note #sidebar, body.single-note #note-list-pane, body.single-note #popout-btn,
body.single-note #resizer-1, body.single-note #resizer-2 { display: none; }

.empty-state { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 14px; color: var(--text-muted); }

/* ---- settings modal --------------------------------------------------------- */
.overlay { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.4); display: flex; align-items: center; justify-content: center; z-index: 100; }
.overlay.hidden { display: none; }

/* Launch login gate — a small Evernote-style sign-in card shown over the whole
   app until a credential is stored. Sits above everything (settings = z 100). */
.login-gate { position: fixed; inset: 0; z-index: 1000; display: flex; align-items: center; justify-content: center; background: var(--editor-bg); }
.login-card { width: 320px; max-width: calc(100vw - 40px); background: var(--modal-bg); border: 1px solid var(--list-border); border-radius: 14px; box-shadow: 0 18px 50px rgba(0, 0, 0, 0.18); padding: 32px 28px; text-align: center; }
.login-logo { font-size: 34px; line-height: 1; }
.login-title { font-size: 22px; font-weight: 700; margin: 10px 0 4px; color: var(--text); }
.login-sub { font-size: 13px; color: var(--text-muted); margin: 0 0 22px; line-height: 1.45; }
.login-btn { display: inline-flex; align-items: center; justify-content: center; gap: 10px; width: 100%; padding: 10px 14px; font-size: 14px; font-weight: 600; color: var(--text); background: var(--input-bg); border: 1px solid var(--list-border); border-radius: 8px; cursor: pointer; transition: border-color .15s, background .15s; }
.login-btn:hover:not(:disabled) { border-color: var(--accent); background: var(--list-hover); }
.login-btn:disabled { opacity: 0.6; cursor: default; }
.login-btn svg { width: 18px; height: 18px; flex: 0 0 18px; }
.login-err { min-height: 16px; margin: 12px 0 0; font-size: 12px; color: var(--status-dropped); }
.login-foot { margin: 18px 0 0; font-size: 11px; color: var(--text-muted); }
/* Secondary text actions on the login/lock card (recheck, switch account). */
.login-link { display: block; width: 100%; margin: 10px 0 0; padding: 4px; background: none; border: none; cursor: pointer;
  font-size: 12px; color: var(--text-muted); text-decoration: underline; text-underline-offset: 2px; }
.login-link:hover { color: var(--accent); }

/* Trial-countdown banner — a thin bar pinned to the top in the trial's final week. */
.trial-banner { position: fixed; top: 0; left: 0; right: 0; z-index: 900; display: flex; align-items: center; gap: 12px;
  justify-content: center; padding: 7px 14px; font-size: 12.5px; color: var(--text);
  background: var(--chip-bg); border-bottom: 1px solid var(--list-border); }
.trial-banner button { font: inherit; cursor: pointer; border-radius: 6px; padding: 3px 10px; line-height: 1.3; }
.trial-banner #trial-up { font-weight: 600; color: #fff; background: var(--accent); border: 1px solid var(--accent); }
.trial-banner #trial-x { color: var(--text-muted); background: none; border: none; padding: 3px 6px; }
.trial-banner #trial-x:hover { color: var(--text); }
.settings-modal { width: 640px; max-width: 90vw; height: 460px; max-height: 88vh; background: var(--modal-bg); border-radius: 12px; box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3); display: flex; flex-direction: column; overflow: hidden; }
.settings-titlebar { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; border-bottom: 1px solid var(--list-border); font-weight: 600; }
.settings-titlebar .icon-btn { color: var(--text-muted); }
.settings-titlebar .icon-btn:hover { background: var(--list-hover); color: var(--text); }
.settings-body { display: grid; grid-template-columns: 160px 1fr; flex: 1; overflow: hidden; }
.settings-nav { background: var(--list-bg); padding: 10px 8px; border-right: 1px solid var(--list-border); }
.settings-nav-group { margin-top: 8px; padding: 10px 12px 4px; border-top: 1px solid var(--list-border); font-size: 10.5px; font-weight: 600; text-transform: uppercase; letter-spacing: .05em; color: var(--text-muted); }
.settings-nav-group:first-child { margin-top: 0; padding-top: 2px; border-top: none; }
.settings-nav-item { padding: 8px 12px; border-radius: 6px; cursor: pointer; color: var(--text); display: flex; align-items: center; gap: 8px; }
.settings-nav-item .lucide { color: var(--text-muted); }
.settings-nav-item.active .lucide, .settings-nav-item:hover .lucide { color: currentColor; }
.settings-nav-item:hover { background: var(--list-hover); }
.settings-nav-item.active { background: var(--accent); color: #fff; }
.settings-pane { padding: 18px 22px; overflow-y: auto; }
.setting-row { display: flex; justify-content: space-between; align-items: center; padding: 10px 0; border-bottom: 1px solid var(--list-border); }
.setting-label { color: var(--text); font-size: 13px; }
.setting-input { border: 1px solid var(--list-border); border-radius: 6px; padding: 4px 8px; background: var(--input-bg); color: var(--text); min-width: 120px; }
.setting-color { width: 44px; height: 28px; border: 1px solid var(--list-border); border-radius: 6px; background: var(--input-bg); cursor: pointer; padding: 2px; }
.setting-note { color: var(--text-muted); font-size: 12px; margin-top: 16px; line-height: 1.5; }
.setting-value { color: var(--text-muted); font-size: 12px; }
.sync-conflict { display: flex; align-items: center; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--list-border); }
.sync-conflict-title { flex: 1; font-size: 13px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sync-conflict-acts { display: flex; gap: 6px; }

/* ---- AI usage board --------------------------------------------------------- */
.usage-board { width: 100%; border-collapse: collapse; margin: 2px 0 14px; }
.usage-board th, .usage-board td { text-align: left; padding: 9px 10px; border-bottom: 1px solid var(--list-border); }
.usage-board thead th { font-size: 11px; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: .04em; }
.usage-board th.usage-kind { font-size: 13px; font-weight: 600; color: var(--text); white-space: nowrap; }
.usage-cell .usage-tokens { font-variant-numeric: tabular-nums; font-weight: 600; color: var(--text); }
.usage-cell .usage-calls { font-size: 12px; color: var(--text-muted); margin-top: 1px; }

/* ---- AI / semantic-search pane ---------------------------------------------- */
.setting-input[type="text"], .setting-input[type="password"] { min-width: 240px; }
.ai-pane .storage-path-actions { margin-top: 12px; }
.ai-key-wrap, .ai-model-wrap { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
.ai-key-wrap .setting-input, .ai-model-wrap .setting-input, .ai-model-wrap select.setting-input { min-width: 200px; }
.ai-key-wrap .ghost-btn, .ai-model-refresh { padding: 4px 10px; font-size: 12px; }
.ai-model-note { flex-basis: 100%; text-align: right; margin-top: 4px; }

/* ---- Local API (MCP) pane --------------------------------------------------- */
.localapi-pane .ai-key-wrap { margin-top: 4px; }
.localapi-pane .ai-key-wrap .setting-input { min-width: 260px; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
textarea.mcp-cmd { width: 100%; margin-top: 8px; resize: vertical; white-space: pre; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12px; line-height: 1.5; }

/* ---- generic modal (prompt / confirm / picker) ------------------------------ */
.modal-box { background: var(--modal-bg); border-radius: 10px; box-shadow: 0 16px 48px rgba(0,0,0,0.3); width: 360px; max-width: 88vw; padding: 18px; }
.modal-title { font-size: 14px; font-weight: 600; margin-bottom: 12px; color: var(--text); }
.modal-input { width: 100%; border: 1px solid var(--list-border); border-radius: 6px; padding: 7px 10px; font-size: 14px; background: var(--input-bg); color: var(--text); }
.modal-input:focus { outline: none; border-color: var(--accent); }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 14px; flex-wrap: wrap; }

/* AI assist toolbar button — deliberately prominent (accent pill) */
.ai-assist-btn { display: inline-flex; align-items: center; gap: 5px; background: var(--chip-bg); color: var(--text-muted);
  border: 1px solid var(--list-border); border-radius: 7px; padding: 6px 14px; font-size: 14px; font-weight: 700; cursor: pointer;
  line-height: 1.4; white-space: nowrap; letter-spacing: 0.01em; }
.ai-assist-btn:hover { background: var(--list-hover); color: var(--text); }
.ai-assist-btn.working { opacity: 0.85; }
.ai-assist-btn.active { border-color: var(--accent); color: var(--text); }

/* Per-note AI progress badge in the middle list */
@keyframes ai-spin { to { transform: rotate(360deg); } }
.ai-badge { flex: 0 0 auto; margin-left: 4px; font-size: 11px; line-height: 1; }
.ai-badge-running { color: var(--accent); display: inline-block; animation: ai-spin 1.2s linear infinite; }
.ai-badge-done { color: var(--accent); }
.ai-badge-error { color: #c0392b; }

/* Fix before/after bar: segmented Current | AI suggestion toggle */
.ai-fix-left { display: inline-flex; align-items: center; gap: 8px; }
.ai-fix-tag { font-size: 12px; font-weight: 600; color: var(--accent); }
.ai-fix-toggle { display: inline-flex; border: 1px solid var(--list-border); border-radius: 6px; overflow: hidden; }
.ai-fix-toggle .seg-btn { background: none; border: none; color: var(--text-muted); padding: 4px 10px;
  font-size: 12px; cursor: pointer; line-height: 1.4; }
.ai-fix-toggle .seg-btn:hover { background: var(--list-hover); }
.ai-fix-toggle .seg-btn.active { background: var(--accent); color: #fff; }

/* ⌘K Velocity Mode — NV-style command palette (input · results · preview) */
.velocity-modal { width: 860px; max-width: 94vw; padding: 0; overflow: hidden;
  display: flex; flex-direction: column; }
.velocity-input { width: 100%; box-sizing: border-box; border: none; outline: none;
  background: transparent; color: var(--text); font-size: 17px; padding: 15px 18px; }
.velocity-body { display: flex; min-height: 0; height: 56vh;
  border-top: 1px solid var(--list-border); }
.velocity-list { list-style: none; margin: 0; padding: 0; flex: 0 0 320px;
  overflow-y: auto; border-right: 1px solid var(--list-border); }
.velocity-item { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  padding: 9px 16px; cursor: pointer; }
.velocity-item.sel { background: var(--selection); box-shadow: inset 3px 0 0 var(--accent); }
.velocity-title { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; color: var(--text); }
.velocity-kind { flex: 0 0 auto; font-size: 11px; color: var(--text-muted); }
.velocity-snippet { flex: 1 0 100%; font-size: 12px; color: var(--text-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.velocity-preview-pane { flex: 1 1 auto; min-width: 0; overflow: hidden; position: relative; }
.velocity-preview-pane .CodeMirror { height: 100%; background: transparent;
  font-size: 13px; color: var(--text); }
.velocity-preview-pane .cm-velocity-match { background: rgba(255, 200, 0, 0.32); border-radius: 2px; }
/* the semantically-matched chunk (markText) — a soft accent wash behind the term hits */
.velocity-preview-pane .velocity-chunk-match { background: color-mix(in srgb, var(--accent) 16%, transparent); border-radius: 2px; }
.velocity-body.no-preview .velocity-preview-pane { display: none; }
.velocity-body.no-preview .velocity-list { flex: 1 1 auto; }
.velocity-footer { display: flex; align-items: center; gap: 12px; padding: 8px 16px;
  border-top: 1px solid var(--list-border); }
.velocity-hint { flex: 1 1 auto; text-align: right; font-size: 12px; color: var(--text-muted); }
/* keyboard-selectable "create in <notebook>" rows */
.velocity-create .velocity-title { color: var(--accent); }
.velocity-create .velocity-kind { color: var(--accent); opacity: 0.85; }
.velocity-create-first { border-top: 1px solid var(--list-border); }
.velocity-create-first::before { content: "Create in notebook"; flex: 1 0 100%;
  order: -1; font-size: 10px; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--text-muted); padding-bottom: 2px; }
.primary-btn.danger { background: var(--status-dropped); }
.danger-btn { display: inline-block; color: var(--status-dropped); border: 1px solid var(--status-dropped); border-radius: 6px; padding: 6px 12px; background: transparent; cursor: pointer; font-size: 13px; margin-top: 16px; }
.danger-btn:hover { background: var(--status-dropped); color: #fff; }
.picker-list { max-height: 240px; overflow-y: auto; margin-top: 4px; }
.picker-item { padding: 8px 10px; border-radius: 6px; cursor: pointer; }
.picker-item:hover, .picker-item.active { background: var(--list-hover); }
.picker-empty { padding: 8px 10px; color: var(--text-muted); }
.bookpick-modal .modal-input { display: block; width: 100%; margin: 8px 0 4px; }

/* ---- context menu ----------------------------------------------------------- */
.context-menu { position: fixed; z-index: 200; background: var(--modal-bg); border: 1px solid var(--list-border); border-radius: 8px; box-shadow: 0 8px 28px rgba(0,0,0,0.25); padding: 5px; min-width: 180px; }
.context-item { display: flex; align-items: center; gap: 10px; padding: 7px 12px; border-radius: 5px; cursor: pointer; font-size: 13px; color: var(--text); white-space: nowrap; }
.context-item:hover { background: var(--accent); color: #fff; }
.context-item.danger { color: var(--status-dropped); }
.context-item.danger:hover { background: var(--status-dropped); color: #fff; }
.context-item.disabled { color: var(--text-muted); cursor: default; }
.context-item.disabled:hover { background: none; color: var(--text-muted); }
.context-item .ctx-label { flex: 1; }
.context-item .ctx-shortcut { color: var(--text-muted); font-size: 11px; opacity: 0.8; }
.context-item:hover .ctx-shortcut { color: rgba(255,255,255,0.65); opacity: 1; }
.context-item.disabled .ctx-shortcut { opacity: 0.4; }
.submenu-arrow { margin-left: auto; opacity: 0.6; font-size: 15px; }
.context-divider { height: 1px; background: var(--list-border); margin: 4px 0; }

/* the open note's notebook / status, marked in the sidebar */
.tree-item.note-here .tree-label, .nav-item.note-here .nav-label { color: var(--accent); font-weight: 600; }
.tree-item.note-here, .nav-item.note-here { box-shadow: inset 2px 0 0 var(--accent); }

/* ---- drag-and-drop ---------------------------------------------------------- */
.drop-target { outline: 2px dashed var(--accent); outline-offset: -2px; background: rgba(33,133,208,0.12) !important; }
body.book-dragging { cursor: grabbing; user-select: none; }
.tree-item.drag-source { opacity: 0.4; }
/* reorder: a clear insertion line above (before) or below (after) the target */
.tree-item.drop-before { box-shadow: inset 0 3px 0 var(--accent); }
.tree-item.drop-after { box-shadow: inset 0 -3px 0 var(--accent); }
/* nest: highlight the whole row + outline so it's obviously "into this notebook" */
.tree-item.drop-target { background: var(--sidebar-active); box-shadow: inset 0 0 0 2px var(--accent); }
/* floating label that follows the cursor while dragging a notebook */
.drag-ghost { position: fixed; z-index: 9999; pointer-events: none; background: var(--accent); color: #fff;
  font-size: 12px; line-height: 1; padding: 4px 8px; border-radius: 5px; box-shadow: 0 2px 10px rgba(0,0,0,0.4); opacity: 0.95; }
.note-item[draggable="true"] { cursor: default; }

/* ---- GitHub-style alerts ---------------------------------------------------- */
.md-alert { border-left: 4px solid var(--text-muted); border-radius: 6px; padding: 8px 14px; margin: 0.7em 0; background: var(--chip-bg); }
.md-alert-title { font-weight: 600; font-size: 0.92em; margin-bottom: 2px; }
.md-alert-body p { margin: 0.2em 0; }
.md-alert-note { border-color: #2185d0; } .md-alert-note .md-alert-title { color: #2185d0; }
.md-alert-tip { border-color: #21ba45; } .md-alert-tip .md-alert-title { color: #21ba45; }
.md-alert-important { border-color: #a333c8; } .md-alert-important .md-alert-title { color: #a333c8; }
.md-alert-warning { border-color: #fbbd08; } .md-alert-warning .md-alert-title { color: #d6a206; }
.md-alert-caution { border-color: #db2828; } .md-alert-caution .md-alert-title { color: #db2828; }

/* ---- <kbd> + highlight.js --------------------------------------------------- */
.markdown-body kbd { background: var(--chip-bg); border: 1px solid var(--list-border); border-bottom-width: 2px; border-radius: 4px; padding: 1px 5px; font-family: var(--font-mono); font-size: 0.85em; }
.markdown-body sub, .markdown-body sup { font-size: 0.75em; }
.markdown-body pre code.hljs { background: transparent; padding: 0; }
.markdown-body img { max-width: 100%; border-radius: 6px; }

/* CodeMirror find/replace dialog — dark theme */
body.theme-dark .CodeMirror-dialog { background: var(--editor-bg); color: var(--text); border-color: var(--list-border); }
body.theme-dark .CodeMirror-dialog input { background: var(--input-bg); color: var(--text); border: 1px solid var(--list-border); }

/* tag color swatch in menus */
.ctx-swatch { width: 11px; height: 11px; border-radius: 50%; flex: 0 0 auto; }

/* PDF export via window.print() — show only the rendered preview */
@media print {
  body { overflow: visible; }
  #sidebar, #note-list-pane, #editor-header, #editor-meta, #editor-toolbar,
  #editor-status-bar, .cm-host, #empty-state, #trash-bar, .overlay, .context-menu { display: none !important; }
  #app { display: block !important; height: auto !important; }
  #editor-pane, #editor-body { display: block !important; overflow: visible !important; }
  #preview { display: block !important; overflow: visible !important; height: auto !important; max-width: 720px; margin: 0 auto; }
}

/* multi-select + batch bar */
.note-item.multi-selected { background: var(--selection); box-shadow: inset 3px 0 0 var(--accent); }
.batch-bar { display: none; align-items: center; gap: 6px; padding: 7px 12px; border-bottom: 1px solid var(--list-border); background: var(--list-hover); flex-wrap: wrap; }
.batch-count { font-size: 12px; font-weight: 600; color: var(--text); margin-right: 4px; }
.batch-btn { background: var(--input-bg); border: 1px solid var(--list-border); border-radius: 6px; padding: 3px 9px; font-size: 12px; cursor: pointer; color: var(--text); }
.batch-btn:hover { border-color: var(--accent); color: var(--accent); }
.batch-btn.batch-clear { margin-left: auto; border: none; background: none; font-size: 14px; }

/* Auth-expired banner — shown when cloud sync fails with HTTP 401 (re-login). */
.auth-banner {
  position: fixed; top: 0; left: 0; right: 0; z-index: 9999;
  display: flex; align-items: center; gap: 12px;
  padding: 8px 14px;
  background: #b42318; color: #fff;
  font-size: 13px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
}
.auth-banner-msg { flex: 1 1 auto; }
.auth-banner-btn {
  flex: 0 0 auto; border: 0; border-radius: 6px;
  padding: 4px 12px; cursor: pointer;
  background: #fff; color: #b42318; font-weight: 600;
}
.auth-banner-x {
  flex: 0 0 auto; border: 0; background: transparent; color: #fff;
  cursor: pointer; font-size: 14px; opacity: 0.85; padding: 2px 6px;
}
.auth-banner-x:hover { opacity: 1; }

/* ═══════════════════════════════════════════════════════════════════════════
   June flavor — components only. The panes stay FLUSH and fill the window; an
   earlier floating "inset card" wasted top/bottom space and read as a box-in-a-
   box because notedrop keeps the native titlebar (June hides it for a tab strip).
   So we keep the warm surfaces + the brand mark, segmented pill, and softened
   chrome, and let the three panes fill edge-to-edge like before. */

/* Brand mark — a clay tile with an "n" (notedrop) seated before the wordmark. */
.brand-mark { display: inline-flex; flex: 0 0 auto; margin-right: 8px; }
.brand-mark svg { display: block; }
.app-name { font-size: 16px; font-weight: 600; }

/* Segmented pill (view-mode switch): a rail with the active segment as a raised
   chip — June's segmented-control treatment, not a solid accent fill. */
.viewmode-group { border: 1px solid var(--list-border); border-radius: 999px; background: var(--chip-bg); padding: 2px; gap: 2px; overflow: visible; margin-right: 6px; }
.vm-btn { border-radius: 999px; padding: 4px 9px; line-height: 1; }
.vm-btn:hover { background: transparent; color: var(--text); }
.vm-btn.active { background: var(--editor-bg); color: var(--accent); box-shadow: 0 1px 2px oklch(24% 0.01 60 / 18%); }
body.theme-dark .vm-btn.active { background: var(--list-hover); }

/* Softer chrome: pill search, rounder selects and buttons, roomier nav rows. */
.search { border-radius: 999px; padding: 7px 13px; }
.mini-select { border-radius: 999px; padding: 3px 9px; }
.nav-item, .tree-item { border-radius: 8px; }
.primary-btn { border-radius: 999px; padding: 7px 15px; }
