:root {
  /* ── Spacing Scale (8px base) ── */
  --space-1:  4px;
  --space-2:  8px;
  --space-3:  12px;
  --space-4:  16px;
  --space-5:  20px;
  --space-6:  24px;
  --space-7:  28px;
  --space-8:  32px;
  --space-10: 40px;
  --space-12: 48px;

  /* ── Typography Scale ── */
  --text-xs:   0.65rem;   /* 10.4px — labels, badges, meta */
  --text-sm:   0.72rem;   /* 11.5px — secondary body, captions */
  --text-base: 0.82rem;   /* 13.1px — primary body text */
  --text-md:   0.90rem;   /* 14.4px — card titles, subheadings */
  --text-lg:   1.00rem;   /* 16px   — modal headings */
  --text-xl:   1.15rem;   /* 18.4px — section headings */
  --text-2xl:  1.40rem;   /* 22.4px — page headings (within content) */
  --text-3xl:  1.70rem;   /* 27.2px — hero headings */

  /* ── Font Weights ── */
  --fw-normal:  400;
  --fw-medium:  500;
  --fw-semi:    600;
  --fw-bold:    700;
  --fw-black:   800;

  /* ── Line Heights ── */
  --lh-tight:  1.25;
  --lh-snug:   1.40;
  --lh-normal: 1.55;
  --lh-relaxed:1.70;
  --lh-loose:  1.85;

  /* ── Consistent component heights ── */
  --h-input:   36px;
  --h-btn-sm:  28px;
  --h-btn-md:  34px;
  --h-btn-lg:  40px;

  /* ── Elevation ──────────────────────────────────────────────────
     Canonical panel shadows. Kept in sync with literature-review.css.
     --shadow-card  → resting elevation for panels/cards sitting on
                      the page (sidebar, list/detail panels, dashboard
                      cards) — the soft lift seen throughout the app.
     --shadow-panel → floating/overlay elevation for anything that
                      pops above the page (modals, dropdowns, popovers,
                      mobile slide-overs). */
  --shadow-card:  0 1px 4px rgba(43, 24, 23, 0.08),
                  0 4px 16px rgba(43, 24, 23, 0.06);
  --shadow-panel: 0 4px 24px rgba(43, 24, 23, 0.12);
}


/* ================================================================
   SECTION 2 — GLOBAL BODY & TEXT REFINEMENTS
   ================================================================ */

/* Consistent base text rendering */
body {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  line-height: var(--lh-normal);
  font-size: var(--text-base);
  background: var(--bg-page);
}

/* Tighten heading tracking globally */
h1, h2, h3, h4, h5, h6 {
  letter-spacing: -0.02em;
  line-height: var(--lh-tight);
}

h1 {
  font-size: 1.5rem !important;
}

  #welcomeHeading {
    font-size: 32px !important;
  }


/* ================================================================
   SECTION 3 — SIDEBAR REFINEMENTS
   
   Issues fixed:
   - Inconsistent icon/text gap (was mixing 9px, 10px, 11px)
   - Side-menu item padding had slight vertical imbalance
   - Bottom user row crowded on some states
   ================================================================ */

/* Unified nav item geometry */
.side-menu li a {
  gap: var(--space-3);            /* 12px — was 11px */
  padding: 8px 10px;
  font-size: var(--text-base);    /* 0.82rem */
  font-weight: var(--fw-medium);
  line-height: var(--lh-snug);
}

.side-menu li a .bx {
  font-size: 16px;                /* unified — was mixed 17px */
  flex-shrink: 0;
  opacity: 0.85;
}

.side-menu li.active a .bx,
.side-menu li a:hover .bx {
  opacity: 1;
}

/* Sidebar bottom: tighter but not cramped */
.sidebar-user {
  padding: 8px 10px 12px;
  gap: var(--space-2);
}

.sidebar-user-name {
  font-size: var(--text-base);
  font-weight: var(--fw-semi);
}

/* Brand row: consistent vertical rhythm */
.brand {
  height: 56px;
  padding: 0 8px 0 12px;
}

.brand-name {
  font-size: 1.1rem;
  letter-spacing: -0.03em;
}


/* ================================================================
   SECTION 4 — MAIN CONTENT AREA
   
   Issues fixed:
   - main padding was 25px on all sides but page topbars added
     their own padding-top, creating ~45px visual gap at top
   - Standardise to a single consistent inset
   ================================================================ */

/* Unified main inset — matches page topbar padding exactly */
#content main {
  padding: var(--space-5); background: var(--bg-page);
}


/* ================================================================
   SECTION 5 — PAGE TOPBARS (Smart Tables, Reports, Dashboard)
   
   Issues fixed:
   - Smart Tables topbar had padding-top: 20px inside main which
     already had its own padding — double gap
   - Report home topbar inconsistently padded vs detail topbar
   - Headings had mixed sizes: 25px, 26px — standardise to 26px
   ================================================================ */

/* Smart Tables topbar */
.st-topbar {
  padding-top: 0;            /* main already provides top space */
  padding-bottom: var(--space-4);
}

.st-topbar-left h1 {
  font-size: 26px;
  font-weight: var(--fw-black);
  letter-spacing: -0.03em;
  line-height: var(--lh-tight);
}

.pg-subtitle,
.st-topbar .pg-subtitle {
  font-size: var(--text-sm);
  color: var(--ink-muted);
  line-height: var(--lh-normal);
  margin-top: 3px;
  display: block;
}

/* Reports home topbar */
.rp-home-topbar {
  padding: 0 0 var(--space-5);  /* remove top, keep bottom border gap */
}

.rp-home-topbar h1 {
  font-size: 26px;
  font-weight: var(--fw-black);
}

/* Reports detail topbar */
.rp-detail-topbar {
  padding: var(--space-3) 0;
}


/* ================================================================
   SECTION 6 — CARDS (Project, Report, Smart Table)
   
   Issues fixed:
   - Card padding inconsistent: 16px, 17px, 18px, 19px scattered
   - Card titles had different font-sizes
   - Footer divider border-top + padding-top inconsistent
   ================================================================ */

/* Unified card padding + elevation — resting shadow so these read as
   lifted cards on the page rather than flat outlined boxes (see the
   dashboard/composer chrome elsewhere in the app for the target look). */
.project-card,
.rp-report-card,
.st-tbl-card {
  padding: 16px 18px;
  box-shadow: var(--shadow-card);
}
.rp-report-card:hover,
.st-tbl-card:hover {
  box-shadow: var(--shadow-panel);
}

/* Card title — unified */
.pc-name,
.rpc-title,
.st-tbl-card-name {
  font-size: var(--text-md);    /* 0.90rem */
  font-weight: var(--fw-bold);
  line-height: var(--lh-snug);
  letter-spacing: -0.015em;
  color: var(--ink);
}

/* Card meta text — unified */
.pc-meta,
.rpc-snippet,
.st-tbl-card-meta {
  font-size: var(--text-sm);    /* 0.72rem */
  color: var(--ink-muted);
  line-height: var(--lh-relaxed);
}

/* Card footer: consistent spacing */
.pc-footer,
.rpc-footer {
  padding-top: var(--space-3);
  margin-top: auto;
  border-top: 1px solid var(--border);
}

/* Card date labels */
.pc-date,
.rli-date,
.rpc-date {
  font-size: var(--text-xs);    /* 0.65rem */
  color: var(--ink-muted);
}


/* ================================================================
   SECTION 8.5 — THREAD WIDTH ALIGNMENT

   .ai-input-dock is pinned to width:700px + margin:0 auto, but
   .ai-thread had no matching constraint and stretched to fill
   .ai-conversation-pane (max-width:1000px). Mirror the dock's box
   model exactly (same width + same horizontal padding) so message
   content lines up edge-to-edge with the input box above/below it.
   ================================================================ */

.ai-thread {
  width: 700px;
  max-width: 100%;
  margin: 0 auto;
  padding-left: 10px;
  padding-right: 10px;
  box-sizing: border-box;
}

/* Empty/welcome state already centers its own content — don't fight it */
.ai-conversation-pane.is-empty .ai-thread {
  width: 100%;
  margin: 0;
}

/* ================================================================
   SECTION 9 — INPUT DOCK (Dashboard AI input)
   
   Issues fixed:
   - .ai-input-toolbar padding-top was 30px — excessive
   - Input box internal padding was 15px — slightly large
   - Toolbar height inconsistent with button sizes
   ================================================================ */

.ai-input-box {
  padding: 10px 14px 12px 14px;
  border-radius: 8px;
}

.ai-input-toolbar {
  padding: var(--space-4) 0 0;  /* 16px top, 8px sides, 0 bottom */
}

.ai-textarea {
  padding: 0px 0 10px 0;                /* box already provides internal padding */
  font-size: var(--text-base);
  line-height: var(--lh-relaxed);
}

.ai-textarea::placeholder {
  font-size: var(--text-base);
}

/* Projects scope button — was a teal "active" pill with an 8px radius
   against a 16px-rounded input box. Both now share an 8px radius, and
   the button uses the box's own neutral border/background language
   instead of the teal "active" toggle color. */
.ai-projscope-btn.ai-active-pill {
  background: var(--bg-card);
  border: 1px solid var(--border);
  color: var(--ink-soft);
  border-radius: 8px;
  font-weight: 600;
}
.ai-projscope-btn.ai-active-pill:hover {
  background: var(--bg-elevated);
  border-color: var(--border-hover);
  color: var(--ink);
  transform: none;
}
.ai-projscope-btn.ai-active-pill i.bx-folder {
  color: var(--ink-muted);
}
.ai-projscope-wrap.open .ai-projscope-btn.ai-active-pill {
  background: var(--bg-elevated);
  border-color: var(--border-hover);
  color: var(--ink);
}

/* Send button — slightly larger hit target */
.ai-send-btn {
  width: 32px;
  height: 32px;
  border-radius: 9px;
  font-size: 1rem;
}


/* ================================================================
   SECTION 10 — BUTTONS
   
   Issues fixed:
   - pill-btn had 8px vertical padding but buttons looked too
     tall next to compact inputs — reduce to 7px
   - Icon gap in buttons was 6px — keep, good
   - .sm variant had 5px top/bottom — leave unchanged
   ================================================================ */

.pill-btn {
  padding: 7px 16px;
  font-size: var(--text-sm);     /* 0.72rem — slightly tighter */
  font-weight: var(--fw-bold);
  letter-spacing: 0.005em;
  gap: 5px;
  height: var(--h-btn-md);       /* 34px — consistent */
}

.pill-btn.sm {
  height: var(--h-btn-sm);       /* 28px */
  padding: 5px 12px;
  font-size: var(--text-xs);
}

/* Ghost buttons: slightly warmer border */
.pill-btn.ghost {
  border-color: var(--border-hover);
  color: var(--ink-soft);
}


/* ================================================================
   SECTION 11 — FORM FIELDS
   
   Issues fixed:
   - Input heights were implicit (padding-based), inconsistent
     across modal forms vs search fields
   - Label font-size was 0.66rem — bumped to 0.68rem for clarity
   ================================================================ */

.form-field label {
  font-size: var(--text-xs);     /* 0.65rem */
  font-weight: var(--fw-black);
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin-bottom: 6px;
  display: block;
}

.form-field input,
.form-field select,
.form-field textarea {
  font-size: var(--text-base);
  padding: 8px 12px;
  min-height: var(--h-input);
  line-height: var(--lh-normal);
}

.form-field textarea {
  min-height: 72px;
  padding: 10px 12px;
}


/* ================================================================
   SECTION 12 — MODALS
   
   Issues fixed:
   - Modal padding was 26px — reduce to 24px for compactness
   - Modal header h2 size was 1.02rem — bring to text-lg: 1.0rem
   - Modal footer gap was 8px — keep
   - Width was 40% which is fine but add min-width for safety
   ================================================================ */

.modal {
  padding: 24px;
  min-width: 380px;
  max-width: 540px;
  width: 44vw;
}

.modal-header {
  margin-bottom: var(--space-4);
}

.modal-header h2 {
  font-size: var(--text-lg);     /* 1.0rem */
  font-weight: var(--fw-black);
  letter-spacing: -0.02em;
  line-height: var(--lh-snug);
}

.modal-footer {
  margin-top: var(--space-4);
  padding-top: var(--space-3);
  gap: var(--space-2);
}

/* Smart Tables modal headers */
.st-modal-header {
  padding-bottom: var(--space-4);
  margin-bottom: var(--space-4);
  border-bottom: 1px solid var(--border);
}

.st-modal-title h2 {
  font-size: var(--text-lg);
  font-weight: var(--fw-black);
  letter-spacing: -0.02em;
}

.st-modal-title p {
  font-size: var(--text-sm);
  color: var(--ink-muted);
  margin-top: 3px;
  line-height: var(--lh-normal);
}

.st-modal-footer {
  padding-top: var(--space-3);
  margin-top: var(--space-4);
  border-top: 1px solid var(--border);
  gap: var(--space-2);
}


/* ================================================================
   SECTION 13 — SECTION LABELS (uppercase micro-labels)
   
   Issues fixed:
   - section-label was 0.67rem — unify to 0.65rem (--text-xs)
   - Inconsistent letter-spacing: 0.07em, 0.08em, 0.09em
     across files — standardise to 0.07em
   ================================================================ */

.section-label,
.st-section-label,
.rdt-label,
.report-toc-label,
.pset-label,
.dz-label {
  font-size: var(--text-xs);
  font-weight: var(--fw-black);
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-muted);
  line-height: var(--lh-snug);
}

/* ================================================================
   SECTION 15 — META STRIPS (date, refs, scope chips)
   
   Issues fixed:
   - rdm-item gap was 4px — keep
   - Meta strip gap between items was 14px — fine but tighten
     in detail view to 12px for tighter feel
   - Icons in meta strips: too much visual noise — dim slightly
   ================================================================ */

.rp-content-meta,
.report-detail-meta,
.rdm-item {
  gap: var(--space-3);           /* 12px — was 14px */
}

.rdm-item i {
  font-size: 0.72rem;
  color: var(--ink-muted);       /* was --teal: subtler */
  opacity: 0.75;
}

.rdm-item + .rdm-item::before {
  content: '·';
  color: var(--ink-muted);
  opacity: 0.35;
  margin-right: var(--space-3);
}


/* ================================================================
   SECTION 16 — SOURCE / REFERENCE CARDS
   
   Issues fixed:
   - ai-ref-card padding was 9px 10px — both axes slightly off
   - Reference title font 0.71rem consistent, keep
   - Source card border was var(--bg-page) — barely visible;
     use proper border token
   ================================================================ */

.ai-ref-card,
.rrp-source-card {
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 9px;
}

.rrp-source-card {
  border-color: var(--border);   /* was --bg-page, too subtle */
}

.ai-ref-title,
.rrp-src-title {
  font-size: 0.72rem;
  font-weight: var(--fw-semi);
  line-height: var(--lh-snug);
  margin-bottom: 3px;
  color: var(--ink);
}

.ai-ref-meta,
.rrp-src-meta {
  font-size: var(--text-xs);
  color: var(--ink-muted);
  line-height: var(--lh-normal);
}


/* ================================================================
   SECTION 19 — SIDEBAR POPUP (Account Modal)
   
   Issues fixed:
   - sp-name was 0.82rem, sp-email 0.70rem — gap is fine
   - sp-item font was 0.82rem — keep
   - sp-settings-body padding 10px all — add slight top padding
   ================================================================ */

.sp-settings-body {
  padding: var(--space-3) var(--space-3) var(--space-4);
}

.sp-field-label {
  font-size: var(--text-xs);
  letter-spacing: 0.07em;
}

.sp-trigger {
  font-size: var(--text-base);
}



/* ================================================================
   SECTION 22 — FOLLOW-UP DOCK
   
   Issues fixed:
   - fu-textarea border-radius was 8px — bump to 9px for unity
   - Send button height was 30px — consistent with other sends
   ================================================================ */

.fu-textarea {
  font-size: var(--text-sm);
  padding: 8px 11px;
  border-radius: 9px;
  line-height: var(--lh-normal);
}

.fu-send-btn {
  width: 32px;
  height: 32px;
  border-radius: 8px;
}


/* ================================================================
   SECTION 23 — EMPTY STATES
   
   Issues fixed:
   - Icon sizes inconsistent: 1.4rem, 1.5rem, 2rem, 2.1rem
   - Heading sizes inconsistent: 0.86rem, 0.88rem, 0.96rem, 1rem
   - Description font: 0.74rem, 0.75rem, 0.76rem, 0.78rem
   ================================================================ */

/* Standardised empty state pattern */
.rp-empty-state,
.reports-list-empty,
.report-detail-empty,
.right-empty-inner,
.ai-ref-empty,
.rrp-empty,
.fu-thread-empty {
  gap: var(--space-3);
  padding: var(--space-10) var(--space-6);
  text-align: center;
}

.ai-thread-empty {
    padding: 0px;
}

.rp-empty-state i,
.reports-list-empty i,
.report-detail-empty i,
.right-empty-inner .bx,
.ai-ref-empty .bx,
.rrp-empty i,
.fu-thread-empty i {
  font-size: 1.6rem;
  color: var(--ink-muted);
}

.rp-empty-state h3,
.reports-list-empty h3,
.report-detail-empty h3,
.right-empty-inner h3 {
  font-size: var(--text-md);     /* 0.90rem */
  font-weight: var(--fw-bold);
  color: var(--ink-soft);
  line-height: var(--lh-snug);
}

.rp-empty-state p,
.reports-list-empty p,
.report-detail-empty p,
.right-empty-inner p,
.ai-ref-empty p,
.rrp-empty p,
.fu-thread-empty p {
  font-size: var(--text-sm);     /* 0.72rem */
  color: var(--ink-muted);
  line-height: var(--lh-relaxed);
  max-width: 240px;
  margin: 0 auto;
}


/* ================================================================
   SECTION 24 — BACK BUTTONS & BREADCRUMBS
   
   Issues fixed:
   - back-btn and rp-back-btn had slightly different font sizes
   - Unified to text-sm with semi weight
   ================================================================ */

.back-btn,
.rp-back-btn,
.st-back-btn {
  font-size: var(--text-sm);
  font-weight: var(--fw-semi);
  padding: 5px 12px;
  gap: 5px;
  height: var(--h-btn-sm);
  border-radius: var(--r-card);
}

.back-btn i,
.rp-back-btn i,
.st-back-btn i {
  font-size: 0.85rem;
}


/* ================================================================
   SECTION 25 — STATUS CHIPS & BADGES
   
   Issues fixed:
   - Chip padding inconsistent: 2px/8px vs 1px/7px vs 3px/10px
   - Font-size: 0.62, 0.63, 0.64, 0.65rem — standardise to 0.63rem
   ================================================================ */

.pc-status,
.rli-type-badge,
.report-detail-badge,
.rpc-meta-chip,
.pub-chip,
.ai-chip,
.stc-tpl-badge {
  font-size: 0.63rem;
  font-weight: var(--fw-black);
  padding: 2px 8px;
  letter-spacing: 0.04em;
}


/* ================================================================
   SECTION 26 — SCROLLBAR POLISH
   
   Ensure all scrollable areas use the same 3–4px subtle scrollbar.
   ================================================================ */

.st-cards-scroll,
.rp-cards-grid,
.report-detail-body,
.rp-content-body,
.ai-thread,
.pub-list,
.pub-detail-body,
.rrp-sources-body,
.rrp-followup-thread,
.pset-tab-panels,
.sidebar-history-list {
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}

.st-cards-scroll::-webkit-scrollbar,
.rp-cards-grid::-webkit-scrollbar,
.report-detail-body::-webkit-scrollbar,
.rp-content-body::-webkit-scrollbar,
.ai-thread::-webkit-scrollbar,
.pub-list::-webkit-scrollbar,
.pub-detail-body::-webkit-scrollbar {
  width: 4px;
}

.st-cards-scroll::-webkit-scrollbar-thumb,
.rp-cards-grid::-webkit-scrollbar-thumb,
.report-detail-body::-webkit-scrollbar-thumb,
.rp-content-body::-webkit-scrollbar-thumb,
.ai-thread::-webkit-scrollbar-thumb,
.pub-list::-webkit-scrollbar-thumb,
.pub-detail-body::-webkit-scrollbar-thumb {
  background: var(--border);
  border-radius: 2px;
}


/* ================================================================
   SECTION 27 — DIVIDERS
   
   Issues fixed:
   - sidebar-divider margin was 6px 12px — tighten top to 4px
   - Modal footer divider uses border-top on .modal-footer; fine
   ================================================================ */

.sidebar-divider {
  margin: 4px 10px;
}

.sp-divider {
  margin: 3px 4px;
}


/* ================================================================
   SECTION 28 — FOCUS RING CONSISTENCY
   
   All focusable inputs should use the same teal glow ring.
   ================================================================ */

.form-field input:focus,
.form-field select:focus,
.form-field textarea:focus,
.pset-input:focus,
.pset-select:focus,
.pset-textarea:focus,
.fu-textarea:focus,
.ai-input-box:focus-within,
.pub-filter-input:focus,
.st-search:focus {
  outline: none;
  border-color: var(--border-focus);
  box-shadow: 0 0 0 3px rgba(13, 167, 154, 0.14);
}

/* Layer the resting lift shadow back in for the input box specifically —
   the shared rule above only covers the focus ring. */
.ai-input-box:focus-within {
  box-shadow: 0 0 0 3px rgba(13, 167, 154, 0.14), 0 1px 2px rgba(43, 24, 23, 0.04), 0 6px 20px rgba(43, 24, 23, 0.09);
}


/* ================================================================
   SECTION 29 — MOBILE REFINEMENTS
   
   Consistent mobile padding and spacing adjustments.
   ================================================================ */

@media (max-width: 768px) {
  #content main {
    padding: var(--space-4) var(--space-4);
  }

  .ai-workflow-cards {
    grid-template-columns: 1fr;
    gap: var(--space-2);
  }

  .modal {
    min-width: 0;
    width: 92vw;
    max-width: 92vw;
    padding: var(--space-4);
  }

  .proj-topbar {
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "crumb   actions"
      "stage   stage";
    row-gap: 10px;
  }
  .proj-topbar .breadcrumb        { grid-area: crumb; }
  .proj-topbar .proj-actions      { grid-area: actions; }
  .proj-topbar .proj-stage-dropdown { grid-area: stage; justify-self: center; }
}

@media (max-width: 480px) {
  #content main {
    padding: var(--space-3) var(--space-3);
  }

  .pill-btn {
    padding: 7px 13px;
  }

  #welcomeHeading {
    font-size: 22px !important;
  }
}


/* ================================================================
   SECTION 30 — PRINT OVERRIDES
   ================================================================ */

@media print {
  #sidebar,
  .rp-detail-topbar,
  .rp-right-panel,
  .ai-input-dock,
  .ai-header-actions {
    display: none !important;
  }

  #content {
    left: 0 !important;
    width: 100% !important;
  }

  .rp-content-body {
    padding: 0 !important;
    overflow: visible !important;
    max-height: none !important;
  }

  body {
    background: white !important;
    color: black !important;
  }
}


/* ================================================================
   SECTION 31 — BUTTON SYSTEM ALIGNMENT
   
   All button variants are unified here. Four families:
   
   A) .pill-btn          — primary action buttons (labelled text)
   B) .icon-btn-sm/xs    — square icon-only utility buttons
   C) .report-export-btn — inline export/action buttons
   D) Send buttons       — .ai-send-btn, .fu-send-btn (circle sends)
   
   Rules applied consistently across all variants:
   - Same transition timing: background 0.16s, border-color 0.16s,
     box-shadow 0.18s, transform 0.1s
   - Same active scale: 0.97
   - Same disabled state: opacity 0.45, cursor not-allowed
   - Same focus ring: 3px teal glow
   - Hover: background shift + border-color shift only (no colour
     jumps — the text colour stays readable, not garish)
   ================================================================ */


/* ── A. PILL BUTTONS ──────────────────────────────────────────── */

.pill-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 7px 16px;
  height: var(--h-btn-md);        /* 34px — consistent hit target */
  border-radius: 20px;
  font-family: inherit;
  font-size: var(--text-sm);      /* 0.72rem */
  font-weight: var(--fw-bold);
  letter-spacing: 0.005em;
  cursor: pointer;
  border: 1px solid transparent;
  transition:
    background 0.16s ease,
    border-color 0.16s ease,
    box-shadow 0.18s ease,
    transform 0.1s ease,
    color 0.16s ease;
  white-space: nowrap;
  flex-shrink: 0;
  line-height: 1;
}

.pill-btn:active  { transform: scale(0.97); }
.pill-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(13, 167, 154, 0.22);
}
.pill-btn:disabled,
.pill-btn[disabled] {
  opacity: 0.45;
  cursor: not-allowed;
  pointer-events: none;
}

/* — Teal / primary — */
.pill-btn.blue {
  background: var(--teal-soft);
  color: var(--teal-dim);
  border-color: var(--teal);
}
.pill-btn.blue:hover {
  background: var(--teal-glow);
}

/* — Ghost — */
.pill-btn.ghost {
  background: transparent;
  color: var(--ink-soft);
  border-color: var(--border-hover);
}
.pill-btn.ghost:hover {
  background: var(--bg-elevated);
  color: var(--ink);
  border-color: var(--border-hover);
}

/* — Red / destructive — */
.pill-btn.red {
  background: var(--red-soft);
  color: var(--red);
  border-color: rgba(220, 38, 38, 0.18);
}
.pill-btn.red:hover {
  background: var(--red);
  color: #fff;
  border-color: var(--red);
}

/* — Small variant — */
.pill-btn.sm {
  height: var(--h-btn-sm);        /* 28px */
  padding: 5px 12px;
  font-size: var(--text-xs);      /* 0.65rem */
}

/* Icon sizing inside pill buttons */
.pill-btn i,
.pill-btn .bx {
  font-size: 0.82rem;
  flex-shrink: 0;
}
.pill-btn.sm i,
.pill-btn.sm .bx {
  font-size: 0.75rem;
}


/* ── B. ICON BUTTONS (square, no label) ──────────────────────── */

/*
  Three sizes:
    .icon-btn-sm  — 30×30px  standard toolbar action
    .icon-btn-xs  — 26×26px  compact in-card action
    .ai-header-icon-btn — 30×30px  header bar actions (same as sm)
    .panel-toggle-btn   — 26×26px  (same as xs)
*/

/* Shared base */
.ti-create-btn,
.icon-btn-sm,
.icon-btn-xs,
.ai-header-icon-btn,
.panel-toggle-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: 1px solid var(--border);
  color: var(--ink-muted);
  cursor: pointer;
  flex-shrink: 0;
  transition:
    background 0.16s ease,
    border-color 0.16s ease,
    color 0.16s ease,
    box-shadow 0.16s ease;
  line-height: 1;
}

.icon-btn-sm,
.ai-header-icon-btn {
  width: 30px;
  height: 30px;
  border-radius: 8px;
  font-size: 0.88rem;
}

.icon-btn-xs,
.panel-toggle-btn {
  width: 26px;
  height: 26px;
  border-radius: 8px;
  font-size: 0.80rem;
}

/* Default hover — neutral lift */
.icon-btn-sm:hover,
.icon-btn-xs:hover,
.ai-header-icon-btn:hover,
.panel-toggle-btn:hover {
  background: var(--bg-elevated);
  color: var(--ink);
  border-color: var(--border-hover);
}

/* Active / toggled state */
.icon-btn-sm.active,
.icon-btn-xs.active,
.ai-header-icon-btn.active,
.panel-toggle-btn.active {
  background: var(--bg-elevated);
  color: var(--ink);
  border-color: var(--border-hover);
}

/* Danger hover (delete, close) */
.icon-btn-sm.danger:hover,
.icon-btn-xs.danger:hover {
  background: var(--red-soft);
  color: var(--red);
  border-color: rgba(220, 38, 38, 0.22);
}

/* Focus ring */
.icon-btn-sm:focus-visible,
.icon-btn-xs:focus-visible,
.ai-header-icon-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(13, 167, 154, 0.18);
}

/* Active press */
.icon-btn-sm:active,
.icon-btn-xs:active {
  transform: scale(0.94);
}


/* ── C. EXPORT / INLINE ACTION BUTTONS ───────────────────────── */

/*
  .report-export-btn — used in report panel header
  .rp-back-btn       — "All Reports" back
  .back-btn          — project view back
  .st-back-btn       — smart tables back
  
  All share the same ghost-like appearance with text + optional icon.
  Unified to the same height and hover behaviour.
*/

.report-export-btn,
.rp-back-btn,
.back-btn,
.st-back-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 13px;
  height: var(--h-btn-sm);        /* 28px */
  border-radius: var(--r-card);
  border: 1px solid var(--border-hover);
  background: none;
  color: var(--ink-soft);
  font-family: inherit;
  font-size: var(--text-sm);      /* 0.72rem */
  font-weight: var(--fw-semi);
  cursor: pointer;
  white-space: nowrap;
  transition:
    background 0.16s ease,
    border-color 0.16s ease,
    color 0.16s ease;
  line-height: 1;
  flex-shrink: 0;
}

.report-export-btn:hover,
.rp-back-btn:hover,
.back-btn:hover,
.st-back-btn:hover {
  background: var(--bg-elevated);
  color: var(--ink);
  border-color: var(--border-hover);
}

/* Primary export variant */
.report-export-btn.primary {
  background: var(--teal);
  color: var(--navy);
  border-color: var(--teal);
  font-weight: var(--fw-bold);
}
.report-export-btn.primary:hover {
  background: var(--teal-dim);
  border-color: var(--teal-dim);
  box-shadow: 0 2px 10px rgba(13, 167, 154, 0.25);
}

/* Smart tables back: teal hover (matches existing intent) */
.st-back-btn:hover {
  background: var(--teal-soft);
  color: var(--teal);
  border-color: var(--teal-border);
}

/* Icon sizing inside these buttons */
.report-export-btn i,
.rp-back-btn i,
.back-btn i,
.st-back-btn i {
  font-size: 0.82rem;
}


/* ── D. SEND BUTTONS (circle/square send) ────────────────────── */

/*
  .ai-send-btn  — main chat send
  .fu-send-btn  — follow-up panel send
  
  Both are teal-filled icon squares. Unified size and transitions.
*/

.ai-send-btn,
.fu-send-btn {
  width: 32px;
  height: 32px;
  border-radius: 9px;
  border: none;
  background: var(--teal);
  color: var(--navy);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1rem;
  flex-shrink: 0;
  transition:
    background 0.16s ease,
    box-shadow 0.18s ease,
    transform 0.1s ease,
    opacity 0.16s ease;
}

/* Slightly dimmed while the input is empty — a soft cue rather than a
   hard disable, since the button stays clickable (it just refocuses the
   textarea on an empty submit). Matches this file's disabled-opacity
   convention (see button section header above) but lighter, since this
   isn't a true disabled state. */
.ai-send-btn.is-empty {
  opacity: 0.55;
}

.ai-send-btn:hover,
.fu-send-btn:hover {
  background: var(--teal-dim);
  box-shadow: 0 2px 12px rgba(13, 167, 154, 0.30);
}

.ai-send-btn:active,
.fu-send-btn:active {
  transform: scale(0.92);
  box-shadow: none;
}

.ai-send-btn:disabled,
.fu-send-btn:disabled {
  background: var(--bg-elevated);
  color: var(--ink-muted);
  cursor: not-allowed;
  box-shadow: none;
  transform: none;
}


/* ── E. SETTINGS BUTTON (toolbar) ────────────────────────────── */

.ai-settings-btn {
  width: 30px;
  height: 30px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--ink-muted);
  font-size: 0.9rem;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  transition:
    background 0.16s ease,
    border-color 0.16s ease,
    color 0.16s ease;
}

.ai-settings-btn:hover {
  background: var(--bg-elevated);
  color: var(--ink);
  border-color: var(--border-hover);
}

.ai-settings-btn.has-settings {
  background: var(--teal-soft);
  color: var(--teal);
  border-color: var(--teal-border);
}


/* ── F. TEXT BUTTONS (inline link-style) ─────────────────────── */

.text-btn {
  background: none;
  border: none;
  color: var(--teal);
  font-family: inherit;
  font-size: var(--text-sm);
  font-weight: var(--fw-semi);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 0;
  transition: opacity 0.16s ease, color 0.16s ease;
  line-height: 1;
}

.text-btn:hover {
  opacity: 0.72;
}


/* ── G. SP (SIDEBAR POPUP) BUTTONS ───────────────────────────── */

/* These live on the dark sidebar surface — separate token set */

.sp-btn {
  flex: 1;
  padding: 6px 10px;
  height: 30px;
  border-radius: 7px;
  border: 1px solid rgba(255, 255, 255, 0.10);
  background: rgba(255, 255, 255, 0.06);
  color: var(--sidebar-ink-soft);
  font-size: 0.77rem;
  font-weight: var(--fw-semi);
  cursor: pointer;
  font-family: inherit;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition:
    background 0.16s ease,
    color 0.16s ease,
    border-color 0.16s ease;
}

.sp-btn:hover {
  background: rgba(255, 255, 255, 0.12);
  color: var(--sidebar-ink);
}

.sp-btn.primary {
  background: var(--teal);
  border-color: transparent;
  color: #fff;
}
.sp-btn.primary:hover {
  background: var(--teal-dim);
}

.sp-btn.red {
  background: rgba(239, 68, 68, 0.14);
  border-color: rgba(239, 68, 68, 0.18);
  color: #ef4444;
}
.sp-btn.red:hover {
  background: rgba(239, 68, 68, 0.26);
  border-color: rgba(239, 68, 68, 0.30);
}

.sp-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}



.rpc-delete-btn,
.rli-delete-btn,
.pc-edit-btn,
.ai-session-delete-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: transparent;
  color: var(--ink-muted);
  cursor: pointer;
  border-radius: 6px;
  font-size: 0.78rem;
  transition:
    opacity 0.15s ease,
    background 0.15s ease,
    color 0.15s ease;
}

/* Revealed on card hover — existing JS/CSS handles the parent trigger,
   these rules just ensure the hover state is consistent */
.rpc-delete-btn:hover,
.rli-delete-btn:hover,
.ai-session-delete-btn:hover {
  background: var(--red-soft);
  color: var(--red);
  opacity: 1;
}

/* Edit button (teal hover rather than red) */
.pc-edit-btn:hover {
  background: var(--teal-soft);
  color: var(--teal);
  opacity: 1;
}
/* ── Status column filter ─────────────────────────────────────────── */
.pt-status-filter-wrap {
  position: relative;
  display: inline-flex;
}

.pt-status-filter-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: none;
  border: none;
  padding: 2px 0;
  font-family: inherit;
  font-size: 0.7rem;
  font-weight: 700;
  color: var(--ink-muted);
  letter-spacing: 0.01em;
  cursor: pointer;
  transition: color 0.14s;
  white-space: nowrap;
}

.pt-status-filter-btn:hover {
  color: var(--ink);
}

.pt-status-filter-btn--active {
  color: var(--teal);
}

.pt-status-filter-btn--active:hover {
  color: var(--teal);
}

#statusFilterCaret {
  font-size: 0.8rem;
  transition: transform 0.18s ease;
  flex-shrink: 0;
}

.pt-status-filter-dropdown {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  min-width: 150px;
  background: var(--bg-surface, #fff);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 4px 20px rgba(0,0,0,0.1);
  padding: 5px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  z-index: 200;
  opacity: 0;
  transform: translateY(-4px);
  pointer-events: none;
  transition: opacity 0.15s ease, transform 0.15s ease;
}

.pt-status-filter-dropdown.open {
  opacity: 1;
  transform: translateY(0);
  pointer-events: all;
}

.pt-sf-chip {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 6px 9px;
  border-radius: 7px;
  border: none;
  background: transparent;
  color: var(--ink-muted);
  font-family: inherit;
  font-size: 0.73rem;
  font-weight: 500;
  cursor: pointer;
  text-align: left;
  transition: background 0.12s, color 0.12s;
  white-space: nowrap;
}

.pt-sf-chip:hover {
  background: var(--sidebar-hover, rgba(0,0,0,0.04));
  color: var(--ink);
}

.pt-sf-chip.active {
  background: var(--teal-soft);
  color: var(--teal);
  font-weight: 600;
}

.pt-sf-all.active {
  background: var(--bg-elevated, rgba(0,0,0,0.04));
  color: var(--ink);
}

.pt-sf-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex-shrink: 0;
}

/* ================================================================
   SECTION 32 — AI CHAT PAGE: PIN SHELL TO VIEWPORT
   
   Issue fixed:
   - On larger screens, the chat topbar and input dock were scrolling
     away with the page instead of staying fixed, and the message
     thread wasn't scrolling on its own.
   - Root cause: #content only sets `min-height: 100vh` (a floor, not
     a ceiling), so once the thread grew tall it just kept expanding
     #content past the viewport instead of clipping. With html/body
     left free to scroll (literature-review.css), the whole document
     took over scrolling — dragging the topbar and input dock, which
     are normal-flow siblings of <main>, along with it. .ai-thread's
     `overflow-y: auto` never got a bounded height to actually scroll
     within, so it just kept growing too.
   - Fix: on the chat page specifically, pin body + #content to the
     viewport height and clip them. That gives the existing flex
     chain (main → .ai-page-wrap → .ai-assistant-section →
     .ai-assistant-body → .ai-conversation-pane → .ai-thread) a real
     bounded height to work with, so .ai-thread becomes the only
     scrolling region and the topbar/input dock stay put.
   - Scoped with :has(.ai-assistant-section) so other pages (Projects,
     Workspace, Exports), which rely on normal document scrolling,
     are unaffected. Left out of the ≤768px range on purpose — mobile
     already opts into full-page scroll via the .ai-page-wrap /
     .ai-assistant-section `height: auto` overrides in the mobile
     media query in literature-review.css.
   ================================================================ */

@media (min-width: 769px) {
  body:has(.ai-assistant-section) {
    height: 100vh;
    overflow: hidden;
  }

  body:has(.ai-assistant-section) #content {
    height: 100vh;
    overflow: hidden;
  }
}

/* ── Icon buttons: disabled state ─────────────────────────────────
   Used by the pub-detail Previous/Next steppers (#pubPrevBtn/#pubNextBtn)
   when there's nothing further to step to. Mirrors .pill-btn:disabled. */
.icon-btn-sm:disabled,
.icon-btn-xs:disabled,
.icon-btn-sm[disabled],
.icon-btn-xs[disabled] {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}

/* ── Full Text Screen — "View All Responses" paired rows ───────────
   fulltext-screen.js's _ftsRowPairHtml renders each publication as two
   <tr>s (assigned human's row, then the AI's row underneath, labelled
   "AI" in the Assigned column) with the Paper cell spanning both via
   rowspan="2". Both rows get the same light border-bottom below —
   between the human/AI rows of one pub and between one pub's pair and
   the next, so every divider in this view reads the same regardless of
   which columns happen to have content on either side of it. The very
   last row in the table still ends up with no border via
   .asv-table tbody tr:last-child (abstract-screen.css), which is more
   specific than the rule below and wins for that one row. Base
   row/cell/pill styling (.asv-table, .asv-answer-pill, etc.) lives in
   abstract-screen.css — these rules only handle the new pairing. */
.fts-table-paired .fts-pair-row--human,
.fts-table-paired .fts-pair-row--ai {
  border-bottom: 1px solid rgba(43,24,23,0.06);
}
/* The base .asv-table td:first-child rule (abstract-screen.css) pins
   whichever cell is first in a row's markup to the left as the sticky
   Paper column. In the AI row there's no Paper <td> — rowspan="2" on the
   human row already covers it — so its first actual cell is really the
   Assigned column, not Paper. Left as-is, that rule still matched it by
   DOM position and pinned it to left:0, rendering the "AI" label on top
   of the real (human row's) Paper cell whenever the table was scrolled
   horizontally. Reset it back to a normal, unpinned cell here. */
.fts-table-paired .fts-pair-row--ai td:first-child {
  position: static;
  left: auto;
  z-index: auto;
  background: transparent;
  padding-left: 16px;
}
/* Chips center vertically in both rows of a pair — without this, a
   wrapped two-line chip stack in one column (e.g. two data-type chips)
   makes that whole row taller, and a single-line cell elsewhere in the
   same row (e.g. the "AI" label) was left stranded at the top instead
   of centered against the row's full height like the human row's. */
.fts-table-paired .fts-pair-row--human td,
.fts-table-paired .fts-pair-row--ai td {
  vertical-align: middle;
}
.fts-table-paired .fts-pair-row--ai td {
  color: var(--ink-muted);
}
.fts-table-paired .fts-pair-row--ai:hover,
.fts-table-paired .fts-pair-row--human:hover {
  background: var(--bg-hover, rgba(0, 0, 0, 0.02));
}
.fts-table-paired td[rowspan] {
  vertical-align: middle;
}
.fts-ai-row-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
/* ================================================================
   SECTION N — SIDEBAR "INVITE TEAMMATES" BOX + POPUP

   Sits between the sidebar divider and the account row, admin-only.
   The box uses the same filled treatment as an *active* nav item
   (var(--sidebar-hover) at rest) rather than plain hover-only text,
   so it reads as a standing action rather than a page link. Clicking
   it reveals a small popup — anchored the same way as the account
   popup — with the workspace join code and a copy button.
   ================================================================ */

.sidebar-invite-box {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: calc(100% - 14px);
  margin: 0 7px 6px;
  padding: 10px 10px;
  border: none;
  border-radius: var(--r-sm);
  background: var(--sidebar-hover);
  color: var(--sidebar-ink-soft);
  font-family: inherit;
  font-size: var(--text-base);
  font-weight: var(--fw-medium);
  text-align: left;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.sidebar-invite-box:hover,
.sidebar-invite-box.open {
  background: var(--sidebar-active);
  color: var(--sidebar-ink);
}
.sidebar-invite-icon {
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  width: 20px; height: 20px;
  color: var(--teal-dim, #0b8f84);
  background: var(--bg-page);
  border-radius: 20px;
  font-size: 15px;
}
.sidebar-invite-text {
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sidebar-invite-chevron {
  flex-shrink: 0;
  font-size: 13px;
  color: var(--sidebar-ink-muted);
}

/* Collapsed sidebar: icon only, centered — mirrors .side-menu li a */
#sidebar.hide .sidebar-invite-box {
  width: 40px;
  margin: 0 auto 6px;
  padding: 8px 0;
  justify-content: center;
}
#sidebar.hide .sidebar-invite-text,
#sidebar.hide .sidebar-invite-chevron {
  display: none;
}

/* ── Popup ── */
.sidebar-invite-popup {
  position: fixed;
  left: 242px;
  bottom: 66px;
  width: 252px;
  background: var(--bg-card);
  border-radius: 12px;
  border: 1px solid var(--sidebar-border);
  padding: 12px;
  z-index: 3000;
  opacity: 0;
  transform: translateY(6px) scale(0.97);
  pointer-events: none;
  transition: opacity 0.18s ease, transform 0.18s ease;
  box-shadow: 0 8px 28px rgba(43, 24, 23, 0.14);
}
.sidebar-invite-popup.open {
  opacity: 1;
  transform: translateY(0) scale(1);
  pointer-events: all;
}
#sidebar.hide ~ .sidebar-invite-popup { left: 68px; }

.sip-header {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  margin-bottom: 10px;
}
.sip-icon {
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  width: 28px; height: 28px;
  border-radius: 50%;
  background: var(--teal-soft, rgba(13,167,154,0.12));
  color: var(--teal-dim, #0b8f84);
  font-size: 14px;
}
.sip-meta { min-width: 0; padding-top: 1px; }
.sip-title {
  font-size: var(--text-base);
  font-weight: var(--fw-bold);
  color: var(--sidebar-ink);
  line-height: var(--lh-tight);
}
.sip-sub {
  font-size: var(--text-xs);
  color: var(--sidebar-ink-muted);
  line-height: var(--lh-snug);
  margin-top: 2px;
}

.sip-code-row {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--sidebar-hover);
  border: 1px solid var(--sidebar-border);
  border-radius: 8px;
  padding: 6px 6px 6px 12px;
}
.sip-code-row code {
  flex: 1; min-width: 0;
  font-family: 'DM Mono', monospace;
  font-weight: 700;
  letter-spacing: 0.14em;
  font-size: 0.9rem;
  color: var(--sidebar-ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sip-code-row code.is-placeholder {
  color: var(--sidebar-ink-muted);
  font-weight: 500;
  letter-spacing: normal;
  font-family: inherit;
  font-size: var(--text-sm);
}
.sip-copy-btn {
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  width: 28px; height: 28px;
  border: none;
  border-radius: 6px;
  background: transparent;
  color: var(--sidebar-ink-muted);
  cursor: pointer;
  font-size: 15px;
  transition: background 0.15s, color 0.15s;
}
.sip-copy-btn:hover { background: var(--teal-soft, rgba(13,167,154,0.10)); color: var(--teal, #0da79a); }
.sip-copy-btn.copied { color: var(--teal, #0da79a); }

.sip-note {
  font-size: var(--text-xs);
  color: var(--sidebar-ink-muted);
  margin-top: 9px;
  line-height: var(--lh-snug);
}
.sip-note strong { color: var(--sidebar-ink-soft); font-weight: var(--fw-semi); }