/* =============================================================
   paper-server frontend
   ============================================================= */

:root {
  /* Neutral palette (slate-ish) */
  --bg: #f7f7f5;
  --panel: #ffffff;
  --panel-soft: #fafaf8;
  --fg: #0b0b0d;
  --fg-soft: #2a2a2f;
  --muted: #5b6371;
  --subtle: #9aa0a6;
  --border: #e7e7e3;
  --border-strong: #d4d4cf;

  /* Accent */
  --accent: #1d4ed8;
  --accent-soft: #e8efff;
  --accent-strong: #1e3a8a;
  --accent-fg-on: #ffffff;

  /* Status colours */
  --success: #15803d;
  --success-soft: #dcfce7;
  --warn: #a16207;
  --warn-soft: #fef3c7;
  --danger: #b91c1c;
  --danger-soft: #fee2e2;

  /* Diff colours */
  --diff-added: #dcfce7;
  --diff-added-fg: #166534;
  --diff-changed: #fef3c7;
  --diff-changed-fg: #92400e;
  --diff-removed: #fee2e2;
  --diff-removed-fg: #991b1b;

  --code-bg: #f3f3ef;
  --code-bg-dark: #0f172a;
  --code-fg-dark: #e2e8f0;

  --radius: 10px;
  --radius-sm: 6px;

  --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI",
    Roboto, Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, "SF Mono", "JetBrains Mono", Menlo,
    Consolas, monospace;
}

/* ---- Dark mode (auto via prefers-color-scheme) ------------------- */
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0b0d12;
    --panel: #14171d;
    --panel-soft: #181c24;
    --fg: #f3f4f6;
    --fg-soft: #d8dbe1;
    --muted: #9ba1ac;
    --subtle: #6b7280;
    --border: #262b34;
    --border-strong: #353c48;

    --accent: #7aa2ff;
    --accent-soft: #1a2540;
    --accent-strong: #b9ccff;
    --accent-fg-on: #0b0d12;

    --success: #4ade80;
    --success-soft: #133324;
    --warn: #fbbf24;
    --warn-soft: #3a2a08;
    --danger: #f87171;
    --danger-soft: #3a1414;

    --diff-added: #143b25;
    --diff-added-fg: #86efac;
    --diff-changed: #3a2a08;
    --diff-changed-fg: #fcd34d;
    --diff-removed: #3a1414;
    --diff-removed-fg: #fca5a5;

    --code-bg: #1a1e26;
  }
}

@supports (font-variation-settings: normal) {
  :root { --font-sans: "Inter var", -apple-system, BlinkMacSystemFont,
    "Segoe UI", Roboto, Helvetica, Arial, sans-serif; }
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-sans);
  font-feature-settings: "cv11", "ss01";
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Visible focus everywhere — better than the browser default. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ----------------- Topbar ----------------- */
.topbar {
  position: sticky; top: 0; z-index: 10;
  background: color-mix(in srgb, var(--panel) 85%, transparent);
  backdrop-filter: saturate(180%) blur(10px);
  -webkit-backdrop-filter: saturate(180%) blur(10px);
  border-bottom: 1px solid var(--border);
}
.topbar-inner {
  max-width: 1080px; margin: 0 auto;
  display: flex; align-items: center;
  padding: 14px 28px;
  gap: 24px;
}
.brand {
  display: inline-flex; align-items: baseline; gap: 10px;
  color: var(--fg); text-decoration: none;
  flex-shrink: 0;
}
.brand:hover { text-decoration: none; }
.brand-name {
  font-weight: 600; font-size: 15px; letter-spacing: -0.01em;
}
.brand-sub {
  color: var(--muted); font-size: 12.5px; font-weight: 400;
  border-left: 1px solid var(--border-strong);
  padding-left: 10px; margin-left: 2px;
}

.tabs {
  margin-left: auto;
  display: flex; gap: 2px;
}
.tab {
  appearance: none; background: none; border: none;
  padding: 7px 12px; font: inherit;
  font-size: 13px; font-weight: 500;
  color: var(--muted);
  cursor: pointer; border-radius: var(--radius-sm);
  transition: color .12s, background .12s;
}
.tab:hover { color: var(--fg); background: var(--code-bg); }
.tab[aria-selected="true"] {
  color: var(--accent); background: var(--accent-soft);
}
/* Back-compat with existing JS that toggles .active. */
.tab.active {
  color: var(--accent); background: var(--accent-soft);
}

@media (max-width: 640px) {
  .topbar-inner { flex-wrap: wrap; gap: 12px; padding: 12px 18px; }
  .brand-sub { display: none; }
  .tabs { margin-left: 0; width: 100%; }
}

/* ----------------- Layout ----------------- */
main {
  max-width: 1080px;
  margin: 0 auto;
  padding: 32px 28px 80px;
}
@media (max-width: 640px) {
  main { padding: 20px 18px 64px; }
}
.panel { display: block; }
.panel[hidden] { display: none; }
.muted { color: var(--muted); font-size: 12.5px; }

/* ----------------- Buttons ----------------- */
button {
  appearance: none;
  background: var(--panel);
  color: var(--fg-soft);
  border: 1px solid var(--border-strong);
  padding: 7px 14px;
  border-radius: var(--radius-sm);
  font: inherit; font-size: 13px;
  cursor: pointer;
  line-height: 1.2;
  transition: background .12s, border-color .12s, color .12s;
}
button:hover:not(:disabled) {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent-strong);
}
button:disabled { opacity: .45; cursor: default; }
button.primary {
  background: var(--accent); color: var(--accent-fg-on); border-color: var(--accent);
}
button.primary:hover:not(:disabled) {
  background: var(--accent-strong); border-color: var(--accent-strong);
  color: var(--accent-fg-on);
}
/* Primary call-to-action — the page's hero action. Bigger touch target,
   slight shadow lift on hover for affordance. */
button.primary-cta {
  font-size: 14px; font-weight: 600;
  padding: 10px 22px;
  letter-spacing: 0.005em;
  box-shadow: 0 1px 2px color-mix(in srgb, var(--accent) 25%, transparent);
}
button.primary-cta:hover:not(:disabled) {
  box-shadow: 0 2px 6px color-mix(in srgb, var(--accent) 35%, transparent);
  transform: translateY(-0.5px);
}
/* Quiet inline link-style button (for "Try example" etc). */
button.link-btn {
  appearance: none;
  background: none;
  border: none;
  padding: 2px 4px;
  font: inherit; font-size: 12.5px;
  color: var(--accent);
  cursor: pointer;
  text-decoration: none;
}
button.link-btn:hover { text-decoration: underline; background: none; color: var(--accent); }

/* ----------------- Search tab ----------------- */
.search-box { margin-bottom: 22px; }
#search-input {
  width: 100%; font-size: 24px; padding: 16px 20px;
  font: inherit; font-size: 24px; font-weight: 500;
  color: var(--fg);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  background: var(--panel);
  outline: none;
  transition: border-color .15s, box-shadow .15s;
  letter-spacing: -0.01em;
}
#search-input::placeholder {
  color: var(--subtle); font-weight: 400;
}
#search-input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 4px var(--accent-soft);
}
.search-meta {
  padding: 8px 4px 0; min-height: 18px;
  color: var(--muted); font-size: 12.5px;
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;
}
.search-kbd-hint { color: var(--subtle); font-size: 12px; }
.search-kbd-hint kbd {
  display: inline-block;
  font-family: var(--font-mono); font-size: 11px;
  padding: 1px 6px; margin: 0 2px;
  border: 1px solid var(--border-strong);
  border-bottom-width: 2px;
  border-radius: 4px;
  background: var(--panel);
  color: var(--fg-soft);
  line-height: 1.4;
}
@media (max-width: 640px) {
  #search-input { font-size: 18px; padding: 12px 14px; }
  .search-kbd-hint { display: none; }
}

.search-results { display: flex; flex-direction: column; gap: 12px; }
.hit {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px 16px;
  display: grid; gap: 6px;
  transition: border-color .12s, background .12s, box-shadow .12s;
}
.hit:hover {
  border-color: var(--border-strong);
}
.hit.featured {
  border-color: var(--accent);
  background: var(--panel);
  box-shadow: 0 1px 3px rgba(29, 78, 216, 0.08);
}
.hit-row1 {
  display: flex; align-items: center; gap: 10px;
}
.hit-title {
  font-weight: 600; font-size: 16px;
  letter-spacing: -0.005em;
  flex: 1; min-width: 0;
  color: var(--fg);
  line-height: 1.35;
}
.hit-row2 {
  color: var(--muted); font-size: 13px;
  display: flex; gap: 12px; align-items: center;
  justify-content: space-between;
}
.hit-meta {
  display: flex; align-items: center; gap: 10px;
  flex: 1; min-width: 0;
  flex-wrap: wrap;
}
.hit-authors {
  color: var(--muted);
  min-width: 0;
}
.hit-links {
  display: flex; gap: 12px;
  flex-shrink: 0;
  margin-left: auto;
}
.hit-link {
  font-size: 12.5px;
  color: var(--accent);
  text-decoration: none;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.hit-link:hover { text-decoration: underline; }

.venue-pill {
  display: inline-flex; align-items: center;
  padding: 2px 9px; border-radius: 999px;
  font-size: 11.5px; font-weight: 600; letter-spacing: .01em;
  background: var(--accent-soft); color: var(--accent-strong);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  flex-shrink: 0;
}

.hit-copy, .hit-view {
  font-size: 11.5px; padding: 4px 10px;
  background: var(--panel-soft);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  color: var(--fg-soft);
  cursor: pointer;
  font-family: inherit;
  flex-shrink: 0;
}
.hit-copy:hover, .hit-view:hover {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent);
}

.score-pill {
  /* score badges have been removed from the UI; class kept for back-compat. */
  display: none;
}

.hit-bibtex {
  margin: 8px 0 0;
  background: var(--code-bg);
  border-radius: var(--radius-sm);
  padding: 12px 14px;
  font-family: var(--font-mono);
  font-size: 12px; line-height: 1.55;
  white-space: pre; overflow-x: auto;
  color: var(--fg-soft);
}
.hit.collapsed .hit-bibtex { display: none; }

.search-empty {
  color: var(--muted); text-align: center;
  padding: 56px 20px; font-size: 13.5px;
}
.search-empty-hint { display: block; margin-top: 8px; font-size: 12.5px; color: var(--subtle); }

/* Inline error / retry surface — used for transient API failures so the
   user sees a friendlier message than "Error: HTTP 500" and can retry
   without re-typing. */
.app-error {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px;
  background: var(--danger-soft);
  border: 1px solid color-mix(in srgb, var(--danger) 30%, transparent);
  color: var(--danger);
  border-radius: var(--radius);
  font-size: 13.5px;
}
.app-error .app-error-msg { flex: 1; color: var(--fg-soft); }
.app-error .app-error-retry {
  font-size: 12.5px; padding: 5px 12px;
  background: var(--panel);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  color: var(--fg-soft); cursor: pointer;
  font-family: inherit;
}
.app-error .app-error-retry:hover {
  background: var(--accent-soft); border-color: var(--accent); color: var(--accent);
}

/* Skeleton loading state -- mirrors .hit card geometry so the page
   doesn't jump when real results land. The shimmer is a moving
   gradient band over a neutral base color. */
.search-skeletons {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.hit.skeleton {
  pointer-events: none;
  border-color: var(--border);
}
.hit.skeleton:hover { border-color: var(--border); }
.sk {
  display: block;
  border-radius: 6px;
  background-color: var(--code-bg, rgba(127, 127, 127, 0.12));
  background-image: linear-gradient(
    90deg,
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, 0.55) 50%,
    rgba(255, 255, 255, 0) 100%
  );
  background-size: 200% 100%;
  background-repeat: no-repeat;
  background-position: -150% 0;
  animation: sk-shimmer 1.2s ease-in-out infinite;
}
.sk-title  { height: 16px; width: 62%; }
.sk-pill   { height: 20px; width: 78px; border-radius: 999px; }
.sk-authors{ height: 12px; width: 40%; }
.sk-link   { height: 12px; width: 64px; }
.sk-meta {
  display: flex; align-items: center; gap: 10px;
  flex: 1; min-width: 0;
}
@keyframes sk-shimmer {
  0%   { background-position: -150% 0; }
  100% { background-position: 250% 0; }
}
/* Stagger subsequent cards a bit so the page doesn't pulse in unison. */
.search-skeletons .hit.skeleton:nth-child(2) .sk { animation-delay: 0.15s; }
.search-skeletons .hit.skeleton:nth-child(3) .sk { animation-delay: 0.30s; }

.search-footer {
  display: flex;
  justify-content: center;
  padding: 8px 0 4px;
}
.load-more-btn {
  font-size: 13px;
  padding: 8px 22px;
  background: var(--panel);
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  color: var(--fg-soft);
  cursor: pointer;
  font-family: inherit;
  letter-spacing: 0.01em;
  transition: border-color .12s, background .12s, color .12s;
}
.load-more-btn:hover {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent);
}
.load-more-btn:disabled {
  cursor: default;
  opacity: 0.6;
}

/* ----------------- Sanitize tab ----------------- */
.sanitize-input { display: flex; flex-direction: column; gap: 10px; }
.sanitize-input-header {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px;
}
.sanitize-output-group { display: flex; flex-direction: column; gap: 10px; }
.sanitize-input label,
.sanitize-output-group label {
  font-weight: 600; font-size: 13px; color: var(--fg);
}
#bibtex-input,
#sanitize-output {
  width: 100%; min-height: 220px;
  padding: 14px 16px;
  font-family: var(--font-mono);
  font-size: 12.5px; line-height: 1.55;
  color: var(--fg-soft);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  background: var(--panel);
  resize: vertical; outline: none;
  box-sizing: border-box;
  display: block;
  transition: border-color .15s, box-shadow .15s;
}
#bibtex-input:focus,
#sanitize-output:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 4px var(--accent-soft);
}
.actions { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.checkbox-inline {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--muted);
  cursor: pointer;
  user-select: none;
}
.checkbox-inline input[type="checkbox"] {
  margin: 0;
  cursor: pointer;
}

.sanitize-results-section {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
/* The HTML `hidden` attribute normally sets display:none, but a
   more-specific CSS `display: flex` wins. Force it back so initial
   page load doesn't reveal the divider/summary above an empty result
   list. */
[hidden] { display: none !important; }
.sanitize-divider {
  border: none;
  border-top: 1px solid var(--border);
  margin: 24px 0 4px;
  height: 0;
}
.sanitize-summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 0 2px;
}
.sanitize-summary-text {
  font-size: 14px;
  color: var(--fg-soft);
  letter-spacing: 0.005em;
  display: flex; align-items: center; gap: 8px;
  flex-wrap: wrap;
}
.sanitize-summary-text strong {
  color: var(--fg);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.sanitize-summary-text .sep { color: var(--subtle); }
/* Status dot before the summary line. Color reflects overall sanitize
   health: green = all matched + no corrections; amber = some corrections;
   red = some entries unverifiable. */
.summary-dot {
  display: inline-block;
  width: 8px; height: 8px; border-radius: 999px;
  background: var(--muted);
  flex-shrink: 0;
}
.summary-dot.ok    { background: var(--success); box-shadow: 0 0 0 3px var(--success-soft); }
.summary-dot.warn  { background: var(--warn);    box-shadow: 0 0 0 3px var(--warn-soft); }
.summary-dot.error { background: var(--danger);  box-shadow: 0 0 0 3px var(--danger-soft); }
.sanitize-summary-text .count.ok    { color: var(--success); }
.sanitize-summary-text .count.warn  { color: var(--warn); }
.sanitize-summary-text .count.error { color: var(--danger); }

/* Output box: editable textarea sized identically to #bibtex-input.
   The Copy button hovers over the top-right corner and fades in on
   hover/focus, mirroring the per-entry diff Copy pattern. */
.sanitize-output-wrap {
  position: relative;
}
.output-copy-btn {
  position: absolute;
  top: 8px;
  right: 8px;
  font-size: 11.5px;
  padding: 4px 12px;
  background: var(--panel);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  color: var(--fg-soft);
  cursor: pointer;
  font-family: inherit;
  opacity: 0;
  transition: opacity .12s, background .12s, border-color .12s, color .12s;
  z-index: 1;
}
.sanitize-output-wrap:hover .output-copy-btn,
.sanitize-output-wrap:focus-within .output-copy-btn,
.output-copy-btn:focus {
  opacity: 1;
}
.output-copy-btn:hover {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent);
}

.sanitize-results { display: flex; flex-direction: column; gap: 16px; }

/* Collapsible "Per-entry details" wrapper around the entry cards.
   Default-open so users see everything after a run; they can fold it
   away once they've confirmed the summary + output box look right. */
.sanitize-details {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 4px;
}
.sanitize-details-summary {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 2px;
  cursor: pointer;
  list-style: none;
  font-size: 13px;
  color: var(--muted);
  user-select: none;
  border-radius: var(--radius-sm);
  transition: color .12s, background .12s;
}
.sanitize-details-summary::-webkit-details-marker { display: none; }
.sanitize-details-summary:hover { color: var(--fg); }
.sanitize-details-summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.sanitize-details-caret {
  font-size: 10px;
  width: 12px;
  text-align: center;
  color: var(--muted);
  transition: transform .15s;
  transform-origin: center;
}
.sanitize-details:not([open]) .sanitize-details-caret {
  transform: rotate(-90deg);
}
.sanitize-details-label {
  font-weight: 600;
  color: var(--fg-soft);
}
.sanitize-details-count {
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.entry {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.entry-header {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 14px;
  background: var(--panel-soft);
  border-bottom: 1px solid var(--border);
  font-size: 13px;
}
.entry-header .entry-index {
  color: var(--muted); font-weight: 600; font-size: 11px;
  background: var(--code-bg); padding: 2px 7px; border-radius: 4px;
  font-variant-numeric: tabular-nums;
}
.entry-header .entry-status { flex: 1; color: var(--muted); }
.entry-header .entry-status.status-verified { color: var(--ok, #1f7a32); }
.entry-header .entry-status.status-unverifiable { color: #a85a00; font-weight: 600; }
.entry-header .entry-status.status-no_match { color: #a23838; font-weight: 600; }
.entry-header .entry-status.status-error { color: #a23838; }
.entry.unverifiable { border-color: #f0c98a; }
.entry.unverifiable .entry-header { background: #fff7e8; }
.entry.no-match { border-color: #f0bdbd; }
.entry.no-match .entry-header { background: #fdf0f0; }

/* Clean entries have no body, so don't draw the header's bottom border
   (otherwise it looks like the body got chopped off). */
.entry.clean .entry-header { border-bottom: none; }
.entry-body .entry-hint {
  margin: 8px 0 0; color: var(--muted); font-size: 12px;
}
.entry-header code {
  font-family: var(--font-mono); font-size: 11.5px;
  color: var(--fg-soft);
}
.entry-body { padding: 14px; display: grid; gap: 16px; }
.entry-body.no-match { background: #fdf6f6; }

/* Verified-entry body has only the diff panel inside; let the panel
   itself own the padding so the bibtex sits flush in the card with no
   double-padding. The grey code background is also unnecessary there
   -- the diff highlighting alone provides enough visual structure. */
.entry.verified .entry-body { padding: 0; }
.entry.verified .diff-bibtex {
  background: transparent;
  border-radius: 0;
  padding: 12px 14px;
}

.diff-bibtex {
  background: var(--code-bg);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: 12px; line-height: 1.6;
  padding: 12px 14px; overflow-x: auto;
  margin: 0;
  white-space: pre;
  color: var(--fg-soft);
}
.diff-bibtex .field-changed {
  background: var(--diff-changed); color: var(--diff-changed-fg);
  display: inline-block; border-radius: 3px; padding: 0 3px; margin: 0 -3px;
}
.diff-bibtex .field-added {
  background: var(--diff-added); color: var(--diff-added-fg);
  display: inline-block; border-radius: 3px; padding: 0 3px; margin: 0 -3px;
}
.diff-bibtex .field-ins {
  background: var(--diff-added); color: var(--diff-added-fg);
  text-decoration: none;
  border-radius: 2px;
  padding: 0 1px;
  font-weight: 600;
}
.diff-bibtex .field-del {
  background: var(--diff-removed); color: var(--diff-removed-fg);
  text-decoration: line-through;
  text-decoration-thickness: 1px;
  border-radius: 2px;
  padding: 0 1px;
  opacity: 0.85;
}
.diff-bibtex .field-changed[data-original]:hover,
.diff-bibtex .field-added[data-original]:hover {
  cursor: help; outline: 1px dashed currentColor; outline-offset: 1px;
}

/* Candidate cards shown under an unverifiable entry */
.entry-candidates {
  display: flex; flex-direction: column; gap: 8px;
  margin-top: 4px;
}
.entry-candidates-label {
  font-size: 12px; color: var(--muted);
  font-weight: 600; letter-spacing: 0.01em;
  margin-bottom: 2px;
}
.candidate {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 10px 12px;
  display: flex; flex-direction: column; gap: 6px;
}
.candidate-row1 {
  display: flex; align-items: center; gap: 10px;
}
.candidate-title {
  flex: 1; font-size: 13.5px; font-weight: 600; color: var(--fg);
  line-height: 1.35; min-width: 0;
}
.candidate-row2 {
  display: flex; align-items: center; gap: 10px;
  font-size: 12px; color: var(--muted);
  justify-content: space-between;
}
.candidate-meta {
  display: flex; align-items: center; gap: 8px;
  flex: 1; min-width: 0;
  flex-wrap: wrap;
}
.candidate-authors { color: var(--muted); min-width: 0; }
.candidate-links {
  display: flex; gap: 10px;
  flex-shrink: 0;
  margin-left: auto;
}
.copy-candidate-bibtex {
  font-size: 11.5px; padding: 4px 10px;
  background: var(--panel-soft);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  color: var(--fg-soft);
  cursor: pointer;
  font-family: inherit;
  flex-shrink: 0;
}
.copy-candidate-bibtex:hover {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent);
}

/* Hover-overlay Copy button anchored to the BibTeX panel. The wrapper is
   positioned so the button can float in the top-right corner; opacity fades
   in on hover/focus so the button stays out of the way when the user just
   wants to read the diff. */
.diff-bibtex-wrap {
  position: relative;
}
.diff-bibtex-wrap .copy-entry-bibtex {
  position: absolute;
  top: 8px;
  right: 8px;
  font-size: 11.5px;
  padding: 4px 12px;
  background: var(--panel);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  color: var(--fg-soft);
  cursor: pointer;
  font-family: inherit;
  opacity: 0;
  transition: opacity .12s, background .12s, border-color .12s, color .12s;
  z-index: 1;
}
.diff-bibtex-wrap:hover .copy-entry-bibtex,
.diff-bibtex-wrap:focus-within .copy-entry-bibtex,
.copy-entry-bibtex:focus {
  opacity: 1;
}
.diff-bibtex-wrap .copy-entry-bibtex:hover {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent);
}

/* ----------------- API tab ----------------- */
.api-panel { display: flex; flex-direction: column; gap: 20px; }
.api-intro {
  color: var(--muted); font-size: 13.5px;
  margin: 0;
}
.api-baseurl {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 8px 12px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  align-self: flex-start;
}
.api-baseurl .label {
  font-size: 10.5px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted);
}
.api-baseurl code {
  font-family: var(--font-mono); font-size: 12.5px;
  color: var(--fg);
}

.endpoint {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px 18px;
  display: flex; flex-direction: column; gap: 10px;
}
.endpoint > header {
  display: flex; align-items: center; gap: 10px;
}
.method {
  display: inline-block;
  font-family: var(--font-mono); font-weight: 700;
  font-size: 11px; letter-spacing: .04em;
  padding: 2px 8px; border-radius: 4px;
  color: #fff;
  flex-shrink: 0;
}
.method.get  { background: #047857; }
.method.post { background: var(--accent); }
.endpoint .path {
  font-family: var(--font-mono); font-size: 13.5px;
  color: var(--fg); font-weight: 500;
}
.endpoint-desc {
  margin: 0; color: var(--fg-soft); font-size: 13.5px;
}
.endpoint-returns {
  margin: 0; color: var(--muted); font-size: 12.5px;
}
.endpoint-returns code {
  font-family: var(--font-mono); font-size: 11.5px;
  background: var(--code-bg);
  padding: 1px 5px; border-radius: 3px;
  color: var(--fg-soft);
}

.codeblock {
  position: relative;
}
.codeblock pre {
  margin: 0;
  background: var(--code-bg-dark);
  color: var(--code-fg-dark);
  border-radius: var(--radius-sm);
  padding: 12px 14px;
  padding-right: 70px; /* leave room for Copy button */
  font-family: var(--font-mono);
  font-size: 12.5px; line-height: 1.55;
  overflow-x: auto;
  white-space: pre;
}
.codeblock code { color: inherit; font-family: inherit; }
.codeblock .copy-curl {
  position: absolute; top: 8px; right: 8px;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.18);
  color: #cbd5e1;
  padding: 4px 10px;
  font-size: 11px;
  border-radius: 4px;
  font-family: var(--font-sans);
}
.codeblock .copy-curl:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.16);
  border-color: rgba(255, 255, 255, 0.3);
  color: #fff;
}

/* ----------------- Toast ----------------- */
.toast {
  position: fixed; bottom: 28px; left: 50%; transform: translateX(-50%);
  background: #0f172a; color: #fff;
  padding: 9px 16px; border-radius: 6px;
  font-size: 13px; opacity: 0; pointer-events: none;
  transition: opacity .2s, transform .2s;
  z-index: 100;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.18);
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(-2px); }

/* ============================================================
   Feedback FAB + Modal
   ============================================================ */
.feedback-fab {
  position: fixed; right: 20px; bottom: 20px;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 16px;
  background: var(--accent); color: var(--accent-fg-on);
  border: 1px solid var(--accent-strong);
  border-radius: 999px;
  font: 600 14px/1 var(--font-sans);
  cursor: pointer;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.18);
  transition: transform .15s ease, box-shadow .15s ease;
  z-index: 90;
}
.feedback-fab:hover { transform: translateY(-1px); box-shadow: 0 10px 28px rgba(0, 0, 0, 0.22); }
.feedback-fab:active { transform: translateY(0); }
.feedback-fab-label { letter-spacing: 0.01em; }
@media (max-width: 540px) {
  .feedback-fab { padding: 12px; }
  .feedback-fab-label { display: none; }
}

.modal {
  position: fixed; inset: 0;
  display: flex; align-items: center; justify-content: center;
  z-index: 200;
}
.modal[hidden] { display: none; }
.modal-backdrop {
  position: absolute; inset: 0;
  background: rgba(11, 13, 18, 0.55);
  backdrop-filter: blur(2px);
}
.modal-card {
  position: relative;
  background: var(--panel);
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: 12px;
  width: min(520px, calc(100% - 32px));
  max-height: calc(100vh - 64px);
  overflow: auto;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.4);
}
.modal-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid var(--border);
}
.modal-header h2 { margin: 0; font-size: 16px; font-weight: 600; }
.modal-close {
  background: transparent; border: 0;
  color: var(--muted); cursor: pointer;
  font-size: 18px; line-height: 1;
  padding: 4px 8px; border-radius: 4px;
}
.modal-close:hover { background: var(--panel-soft); color: var(--fg); }
.modal-body { padding: 18px 20px 20px; }

.feedback-form { display: flex; flex-direction: column; gap: 6px; }
.feedback-form label { font-size: 12px; font-weight: 600;
  color: var(--muted); letter-spacing: 0.02em; text-transform: uppercase; margin-top: 8px; }
.feedback-form label .muted { font-weight: 400; text-transform: none; letter-spacing: 0; }
.feedback-form select,
.feedback-form input[type="text"],
.feedback-form textarea {
  font: inherit;
  background: var(--panel-soft);
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 12px;
}
.feedback-form textarea { resize: vertical; min-height: 100px; font-family: var(--font-sans); }
.feedback-form select:focus,
.feedback-form input:focus,
.feedback-form textarea:focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-color: var(--accent);
}
.feedback-actions {
  margin-top: 12px;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.feedback-success {
  background: var(--success-soft);
  color: var(--success);
  border: 1px solid color-mix(in srgb, var(--success) 30%, transparent);
  padding: 10px 14px; border-radius: 8px;
  font-weight: 500;
  margin-bottom: 12px;
}

/* ============================================================
   Stats dashboard
   ============================================================ */
.tab-hidden { display: none; }
.tab-hidden[aria-selected="true"] { display: inline-flex; }

.stats-auth {
  max-width: 420px; margin: 60px auto;
  background: var(--panel);
  border: 1px solid var(--border); border-radius: 12px;
  padding: 28px;
  text-align: center;
}
.stats-auth h2 { margin: 0 0 6px; font-size: 18px; }
.stats-auth p { margin: 0 0 16px; }
.stats-auth-form { display: flex; gap: 8px; }
.stats-auth-form input {
  flex: 1; font: inherit;
  background: var(--panel-soft); color: var(--fg);
  border: 1px solid var(--border); border-radius: 8px;
  padding: 10px 12px;
}
.stats-auth-error { color: var(--danger); font-size: 13px; margin-top: 12px; }

.stats-dashboard { display: flex; flex-direction: column; gap: 24px; padding: 8px 0 24px; }
.stats-toolbar {
  display: flex; align-items: center; gap: 16px;
  padding-bottom: 4px;
}
.stats-toolbar .muted { margin-left: auto; font-size: 12px; }

.stats-grid {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}
.stats-card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px 16px;
}
.stats-card-label {
  font-size: 11px; font-weight: 600; letter-spacing: 0.05em;
  color: var(--muted); text-transform: uppercase;
}
.stats-card-value {
  font-size: 28px; font-weight: 700; line-height: 1.1;
  margin-top: 4px; font-variant-numeric: tabular-nums;
}
.stats-card-sub { font-size: 12px; color: var(--muted); margin-top: 4px; }

.stats-section {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px 18px;
}
.stats-section h3 {
  margin: 0 0 12px;
  font-size: 13px; font-weight: 600; letter-spacing: 0.03em;
  color: var(--muted); text-transform: uppercase;
}

.stats-two-col {
  display: grid; gap: 16px;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}

.stats-sparkline-wrap { width: 100%; height: 80px; }
#stats-sparkline { width: 100%; height: 100%; display: block; }
#stats-sparkline .bar { fill: var(--accent); opacity: 0.85; }
#stats-sparkline .bar:hover { opacity: 1; }
#stats-sparkline .axis { stroke: var(--border); stroke-width: 1; }
#stats-sparkline text { fill: var(--muted); font: 10px var(--font-mono); }

.stats-table {
  width: 100%; border-collapse: collapse; font-size: 13px;
}
.stats-table th, .stats-table td {
  text-align: left; padding: 8px 10px;
  border-bottom: 1px solid var(--border);
  font-variant-numeric: tabular-nums;
}
.stats-table th {
  font-size: 11px; font-weight: 600; letter-spacing: 0.04em;
  color: var(--muted); text-transform: uppercase;
}
.stats-table td.endpoint { font-family: var(--font-mono); font-size: 12px; }
.stats-table td.num { text-align: right; }
.stats-table tr:last-child td { border-bottom: 0; }

.stats-kv { width: 100%; font-size: 13px; }
.stats-kv td { padding: 6px 0; }
.stats-kv td:first-child { color: var(--muted); }
.stats-kv td:last-child { text-align: right; font-weight: 600; font-variant-numeric: tabular-nums; }

.stats-list { margin: 0; padding-left: 24px; font-size: 13px; }
.stats-list li { padding: 4px 0; display: flex; justify-content: space-between; gap: 12px; }
.stats-list li .q { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stats-list li .n { color: var(--muted); font-variant-numeric: tabular-nums; }

.stats-feedback-list { display: flex; flex-direction: column; gap: 8px; }
.feedback-item {
  border: 1px solid var(--border); border-radius: 8px;
  padding: 10px 12px;
  background: var(--panel-soft);
  display: grid; grid-template-columns: auto 1fr auto; gap: 10px;
  align-items: start;
}
.feedback-item .cat {
  font-size: 11px; padding: 3px 8px; border-radius: 999px;
  text-transform: uppercase; letter-spacing: 0.04em;
  font-weight: 600;
  align-self: start;
}
.feedback-item .cat-bug    { background: var(--danger-soft); color: var(--danger); }
.feedback-item .cat-idea   { background: var(--accent-soft); color: var(--accent); }
.feedback-item .cat-praise { background: var(--success-soft); color: var(--success); }
.feedback-item .cat-other  { background: var(--panel); color: var(--muted); border: 1px solid var(--border); }
.feedback-item .body { min-width: 0; }
.feedback-item .body .meta { font-size: 11px; color: var(--muted); margin-bottom: 4px; }
.feedback-item .body .msg { font-size: 13px; white-space: pre-wrap; word-break: break-word; }
.feedback-item .body .contact { font-size: 12px; color: var(--muted); margin-top: 4px; font-family: var(--font-mono); }
.feedback-item .status { font-size: 11px; }
.feedback-item .status select {
  background: var(--panel); color: var(--fg);
  border: 1px solid var(--border); border-radius: 6px;
  padding: 2px 6px; font-size: 11px;
}
.feedback-item.status-closed   { opacity: 0.65; }
.feedback-item.status-triaged  { border-color: color-mix(in srgb, var(--warn) 40%, var(--border)); }

.stats-badge {
  display: inline-block;
  background: var(--danger); color: #fff;
  font-size: 11px; padding: 1px 8px; border-radius: 999px;
  margin-left: 6px; vertical-align: middle; font-weight: 600;
  text-transform: none; letter-spacing: 0;
}

.stats-blocked-list { display: flex; flex-direction: column; gap: 6px; font-size: 13px; }
.blocked-item {
  display: grid; grid-template-columns: 1fr auto auto auto; gap: 12px;
  align-items: center;
  padding: 6px 10px; border: 1px solid var(--border); border-radius: 6px;
  background: var(--panel-soft);
  font-family: var(--font-mono); font-size: 12px;
}
.blocked-item .reason { font-family: var(--font-sans); color: var(--muted); }
.blocked-item .ts { color: var(--muted); }
.blocked-item button {
  background: transparent; color: var(--danger);
  border: 1px solid var(--danger); border-radius: 4px;
  padding: 2px 8px; font-size: 11px; cursor: pointer;
}
.blocked-item button:hover { background: var(--danger-soft); }
