/* =========================================================
   UN Human Rights Database · Component layer
   ========================================================= */

/* ─────────────  APP SHELL (v19.43-fix3)  ─────────────
   Single scroll-axis layout. The viewport is locked: <html> + <body>
   fill 100vh and never scroll. Mast + searchbar + scope sit at the top
   in normal flex flow (no sticky, no shrink). The 4-column .layout
   below them takes all remaining vertical space; each of its three
   visible children (.filters, .results, .dossier) gets its own
   overflow:auto, so the user has exactly ONE scrollable region per
   pane and zero ambiguity about which axis moves.
   The --mast-h variable is preserved (other code reads it) but is no
   longer used for sticky offsets — kept at a stable value. */
:root {
  --mast-h: 0px;        /* legacy var; sticky offsets no longer needed */
  --shell-pad: 40px;    /* horizontal page padding */
}
html, body {
  height: 100vh;
  margin: 0;
  overflow: hidden;     /* lock the window — scroll lives inside panes */
}
body {
  display: flex;
  flex-direction: column;
  min-height: 0;
}
/* The search view section is the flex child that holds the scope/search/main
   stack. Document/Workspace/About views replace it via the router.
   v19.43-fix5: flex: 1 1 0 (not 1 1 auto) so flex-basis ignores intrinsic
   content size — otherwise Chrome resolves flex-basis: auto against the
   children's natural height (huge), then growth never happens because the
   column already "thinks" it's big enough. */
section[data-view] {
  display: flex;
  flex-direction: column;
  flex: 1 1 0;
  min-height: 0;
}
section[data-view="search"],
section[data-view="documents"] {
  overflow: hidden;       /* nested panes scroll */
}
section[data-view="workspace"],
section[data-view="about"] {
  overflow-y: auto;       /* full-section scroll for content-only views */
}
section[data-view][hidden] { display: none; }

/* ─────────────  MASTHEAD  ─────────────
   No longer sticky and no longer shrinks. The whole mast block is
   always visible at full size; the editorial title is part of the
   permanent app frame, not a reactive element. */
.mast {
  border-bottom: 1px solid var(--ink);
  background: var(--paper);
  padding: 14px var(--shell-pad) 10px;
  flex: 0 0 auto;
  z-index: 45;
}
.mast--compact {
  /* Retained so any leftover toggle from old sessions or stray code
     paths is a no-op rather than a layout shift. */
  padding: 14px var(--shell-pad) 10px;
}
.mast-row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 32px;
  flex-wrap: wrap;
}
/* v19.43-fix3: app-shell pattern. .mast--compact is intentionally a
   no-op now — the masthead never shrinks because the page never
   scrolls. The class is kept on the element so legacy code that
   listens for it stays harmless. */
.mast-brand { min-width: 0; }
.mast-title {
  margin: 4px 0 0;
  font-size: 36px;
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: 1;
  color: var(--ink);
}
.mast-sub {
  font-style: italic;
  color: var(--ink-3);
  font-size: 13px;
  margin-top: 4px;
}
#mast-folio {
  display: flex;
  align-items: center;
  gap: 12px;
}
/* v19.43: thin progress bar inside the folio strip — replaces the
   "LOADING…" string. Stays hidden once boot completes (width = 100%
   reaches the end and the bar fades). */
.mast-folio-bar {
  flex: 1 1 auto;
  max-width: 200px;
  height: 1px;
  background: var(--rule, #d4cdc1);
  position: relative;
  overflow: hidden;
  transition: opacity 0.4s ease 0.5s;   /* fade out 0.5 s after width hits 100% */
}
.mast-folio-bar-fill {
  display: block;
  height: 100%;
  width: 0%;
  background: var(--garnet);
  transition: width 0.25s ease;
}
/* Once 100% is reached, the inline style sets width:100%; we then
   fade the bar away (transitioned). */
.mast-folio-bar:has(.mast-folio-bar-fill[style*="100%"]) {
  opacity: 0;
}
.mast-nav {
  display: flex;
  gap: 22px;
  align-items: center;
  font-family: var(--display);
  font-size: 14px;
}
.mast-nav a {
  color: var(--ink-2);
  text-decoration: none;
  padding-bottom: 2px;
}
.mast-nav a:hover { color: var(--ink); }
.mast-nav a.active {
  color: var(--garnet);
  border-bottom: 2px solid var(--garnet);
}
.mast-sep {
  width: 1px;
  height: 18px;
  background: var(--rule);
}
#theme-toggle {
  font-family: var(--mono);
  font-size: 14px;
  padding: 4px 10px;
}

/* ─────────────  SCOPE / SOURCE  ─────────────
   v19.43-fix9: scope buttons live in the left filter pane as a
   vertical list. The .scope-bar (full-width horizontal strip above
   the layout) is gone; .scope-opt class + data-scope attribute kept
   so existing JS handlers in bindUI() still wire correctly. */
.filter-block-source {
  /* Visual delimiter from regular filters — Source is a top-level
     dataset partition, not a filter on the active dataset. */
  padding-bottom: 18px;
  border-bottom: 1px solid var(--rule);
  margin-bottom: 18px;
}
.scope-list {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--rule);
  background: var(--paper);
}
/* Two-row grid per scope-opt: name on top (left col), count
   detail on bottom (left col, dimmer + smaller), PREVIEW badge
   on right spanning both rows. Avoids the squash that happens
   when "3117 · 3 bodies" fights with "Jurisprudence" on one row. */
.scope-opt {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  column-gap: 8px;
  row-gap: 2px;
  width: 100%;
  font-family: var(--display);
  font-size: 13px;
  background: transparent;
  color: var(--ink-2);
  border: 0;
  border-bottom: 1px solid var(--rule);
  padding: 8px 12px;
  cursor: pointer;
  letter-spacing: 0.01em;
  text-align: left;
  transition: background .12s, color .12s;
}
.scope-opt:last-child { border-bottom: 0; }
.scope-opt-name {
  grid-column: 1 / 2;
  grid-row: 1 / 2;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.scope-opt:hover { background: var(--paper-3); color: var(--ink); }
.scope-opt.is-active {
  background: var(--paper-3);
  color: var(--ink);
  box-shadow: inset 3px 0 0 var(--garnet);
}
.scope-opt.is-active .scope-count { color: var(--ink-3); }
.scope-count {
  grid-column: 1 / 2;
  grid-row: 2 / 3;
  font-family: var(--mono);
  font-size: 10px;
  color: var(--ink-3);
  font-feature-settings: "tnum";
  letter-spacing: 0.02em;
}
.scope-count:empty,
.scope-count:not([id]):empty { display: none; }
.scope-opt .badge {
  grid-column: 2 / 3;
  grid-row: 1 / 3;
  align-self: center;
  font-size: 9px;
  padding: 2px 5px;
  flex: 0 0 auto;
}

/* Onboarding banner for SP scope — now inline below the source list,
   constrained to the filter-block-source margin. */
.scope-banner {
  position: relative;
  margin: 12px 0 0;
  padding: 10px 26px 10px 12px;
  background: var(--preview-soft);
  border-left: 3px solid var(--preview);
  font-family: var(--body);
  font-size: 12px;
  line-height: 1.5;
  color: var(--ink-2);
}
.scope-banner .folio {
  color: var(--preview);
  font-weight: 600;
  display: inline;
  margin-right: 10px;
}
.scope-banner strong {
  font-weight: 600;
  color: var(--ink);
}
.scope-banner .mandate-list {
  display: block;
  margin-top: 4px;
  font-size: 12px;
  color: var(--ink-2);
  font-feature-settings: "tnum";
}
.banner-dismiss {
  position: absolute;
  top: 6px;
  right: 8px;
  background: transparent;
  border: 0;
  color: var(--ink-3);
  font-size: 18px;
  cursor: pointer;
  padding: 0 6px;
  line-height: 1;
}
.banner-dismiss:hover { color: var(--ink); }

/* ─────────────  SEARCH BAR  ───────────── */
.searchbar {
  border-bottom: 1px solid var(--rule);
  padding: 18px 40px;
  background: var(--paper);
  flex: 0 0 auto;
}
.searchbar-inner {
  display: flex;
  align-items: center;
  gap: 16px;
  position: relative;             /* anchors the recent-searches popover */
}

/* v19.51.7 (Tier B.1): recent-searches popover under #q. Anchored to
   `.searchbar-inner` (position:relative above). Shown only when the
   input is focused-and-empty AND localStorage has at least one entry. */
.q-recent {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  margin-top: 6px;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 4px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
  z-index: 30;
  max-height: 320px;
  overflow-y: auto;
  padding: 6px 0;
}
.q-recent-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 6px 14px;
  border-bottom: 1px solid var(--rule-soft);
  margin-bottom: 4px;
}
.q-recent-clear {
  background: none;
  border: 0;
  padding: 2px 6px;
  font-family: var(--mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ink-3);
  cursor: pointer;
  border-radius: 2px;
}
.q-recent-clear:hover { color: var(--garnet); background: var(--paper-2); }
.q-recent-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.q-recent-opt {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  width: 100%;
  background: none;
  border: 0;
  padding: 6px 14px;
  text-align: left;
  font-family: var(--display);
  font-size: 14px;
  color: var(--ink);
  cursor: pointer;
  gap: 12px;
}
.q-recent-opt:hover,
.q-recent-opt:focus-visible {
  background: var(--paper-2);
  outline: none;
}
.q-recent-q {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.q-recent-ago {
  flex: 0 0 auto;
  font-size: 10px;
  color: var(--ink-3);
}

/* v19.51.7 (Tier B.3): keyboard shortcuts modal. Native <dialog>
   gives us backdrop, focus-trap, and Esc-to-close for free. */
.shortcuts-modal {
  border: 1px solid var(--rule);
  border-radius: 6px;
  background: var(--paper);
  color: var(--ink);
  padding: 24px 28px;
  max-width: 480px;
  font-family: var(--display);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.18);
}
.shortcuts-modal::backdrop {
  background: rgba(0, 0, 0, 0.35);
}
.shortcuts-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}
.shortcuts-close {
  background: none;
  border: 0;
  font-size: 22px;
  line-height: 1;
  color: var(--ink-3);
  cursor: pointer;
  padding: 0 6px;
}
.shortcuts-close:hover { color: var(--garnet); }
.shortcuts-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 10px;
}
.shortcuts-list li {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: 14px;
}
.shortcuts-modal kbd {
  display: inline-block;
  padding: 2px 8px;
  background: var(--paper-2);
  border: 1px solid var(--rule);
  border-bottom-width: 2px;
  border-radius: 3px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink);
  min-width: 18px;
  text-align: center;
}
.shortcuts-help {
  color: var(--ink-2);
}
.shortcuts-or {
  font-size: 11px;
  font-style: italic;
  color: var(--ink-3);
  margin: 0 4px;
}
.shortcuts-foot {
  margin: 16px 0 0;
  padding-top: 12px;
  border-top: 1px solid var(--rule-soft);
  font-size: 12px;
  color: var(--ink-3);
  font-style: italic;
}
.search-prompt {
  font-size: 22px;
  font-style: italic;
  color: var(--ink-3);
  font-weight: 400;
  flex-shrink: 0;
}
.search-input {
  flex: 1;
  font-family: var(--display);
  font-size: 22px;
  font-weight: 400;
  background: transparent;
  border: 0;
  outline: none;
  color: var(--ink);
  border-bottom: 1px solid var(--ink-3);
  padding: 6px 0;
}
.search-input:focus { border-bottom-color: var(--garnet); }
.search-input::placeholder {
  color: var(--ink-4);
  font-style: italic;
}
/* v19.18: suppress WebKit/Chromium's built-in <input type="search"> clear
   icon. We render our own .q-clear-btn for cross-browser consistency
   (Firefox doesn't show the native one), so the native + custom were
   stacking as two visible × glyphs. Affects Safari + Chrome + mobile. */
.search-input::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
  display: none;
}
.search-input::-webkit-search-decoration {
  -webkit-appearance: none;
  appearance: none;
}
#result-count {
  flex-shrink: 0;
  font-feature-settings: "tnum";
  min-width: 80px;
  text-align: right;
}

/* Inline × clear button on the search input */
.q-clear-btn {
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 1px solid var(--rule);
  background: var(--paper-2);
  color: var(--ink-3);
  cursor: pointer;
  font-size: 16px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--display);
  padding: 0;
  margin: 0 4px 0 -8px;
  transition: background 0.12s, color 0.12s;
}
.q-clear-btn:hover {
  background: var(--garnet);
  color: var(--paper);
  border-color: var(--garnet);
}

/* v19.17 (recommendation D): always-accessible search-syntax help.
   Sits right after the clear chip; same circle-button vocabulary so
   the two affordances read as a pair. Stays visible whether or not
   the input has content. The popover itself is appended to <body>
   so it can overflow the searchbar without clipping. */
.q-help-btn {
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 1px solid var(--rule);
  background: var(--paper-2);
  color: var(--ink-3);
  cursor: pointer;
  font-size: 13px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--display);
  padding: 0;
  margin: 0 6px 0 0;
  transition: background 0.12s, color 0.12s;
}
.q-help-btn:hover,
.q-help-btn[aria-expanded="true"] {
  background: var(--garnet);
  color: var(--paper);
  border-color: var(--garnet);
}

.q-help-pop {
  position: absolute;
  z-index: 40;
  min-width: 360px;
  max-width: 460px;
  background: var(--paper);
  border: 1px solid var(--ink);
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.14);
  padding: 16px 18px 14px;
  font-family: var(--body);
  color: var(--ink);
}
.q-help-pop h4 {
  margin: 0 0 8px 0;
  font-family: var(--display);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  font-weight: 500;
}
.q-help-pop h4:not(:first-child) { margin-top: 14px; }
.q-help-pop dl {
  margin: 0;
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 6px 14px;
  font-size: 13px;
}
.q-help-pop dt {
  font-family: var(--mono);
  color: var(--garnet);
  white-space: nowrap;
}
.q-help-pop dd {
  margin: 0;
  color: var(--ink-2);
  line-height: 1.45;
}
.q-help-pop .q-help-examples {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.q-help-pop .q-help-example {
  font-family: var(--mono);
  font-size: 12px;
  padding: 4px 8px;
  background: var(--paper-2);
  border: 1px solid var(--rule);
  color: var(--ink-2);
  cursor: pointer;
  border-radius: 2px;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.q-help-pop .q-help-example:hover {
  background: var(--garnet);
  color: var(--paper);
  border-color: var(--garnet);
}
.q-help-pop .q-help-tip {
  margin: 0;
  font-size: 12px;
  color: var(--ink-3);
  line-height: 1.5;
}
.q-help-pop .q-help-tip code {
  font-family: var(--mono);
  font-size: 11px;
  background: var(--paper-2);
  padding: 1px 5px;
  border-radius: 2px;
}

/* GC / SP result breakdown pills (next to the result count, in scope=All) */
.result-breakdown {
  flex-shrink: 0;
  display: inline-flex;
  gap: 6px;
  align-items: center;
  margin-left: 8px;
  font-feature-settings: "tnum";
}
.rb-pill {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.04em;
  padding: 2px 7px;
  border-radius: 3px;
  border: 1px solid var(--rule);
  color: var(--ink-2);
}
.rb-pill.rb-gc { background: var(--paper-2); }
.rb-pill.rb-sp {
  background: var(--preview-soft, #f5f1ee);
  color: var(--preview, var(--ink-2));
  border-color: var(--preview, var(--rule));
}
.rb-pill.rb-jur {
  background: var(--jur-soft);
  color: var(--jur-tone);
  border-color: var(--jur-tone);
}
/* v19: live "API · NN ms" pill that appears when ?api=1 is active. */
.rb-pill.rb-api {
  background: var(--paper-3);
  color: var(--garnet);
  border-color: var(--garnet);
  font-feature-settings: "tnum";
}

/* v19.43: progressive disclosure — Export, Copy link, and Save search
   only show once there are results to operate on. On first paint with
   no query / no results, the searchbar shrinks to: prompt + input +
   clear + ? + count. Decluttered to ~6 elements (vs. 14). */
body:not(.has-results) #export-menu,
body:not(.has-results) #copy-link,
body:not(.has-results) #save-search,
body:not(.has-results) .result-breakdown {
  display: none !important;
}
/* v19.50.1 (audit Step 3.C / A1): when the boot-time pingApi appended
   the API badge inside .result-breakdown, the no-results state hid
   the badge along with the pills. Force the breakdown wrap visible
   when an api-badge is present, so the connectivity indicator shows
   even before the user runs a search. The GC/JUR/SP pills stay
   individually hidden via paintResultBreakdown until results arrive. */
body:not(.has-results) .result-breakdown:has(#api-badge) {
  display: inline-flex !important;
}

/* v19.43: "More views…" disclosure for the result-grouping segmented
   control. Hides "By treaty body" (rare) behind a … chip; click to
   reveal. Keeps the default Paragraphs/Documents segment clean. */
.result-more-views {
  display: inline-block;
  position: relative;
}
.result-more-views > summary {
  list-style: none;
  cursor: pointer;
  user-select: none;
  /* inherits .result-opt styling for consistent look */
}
.result-more-views > summary::-webkit-details-marker { display: none; }
.result-opt-more {
  font-size: 14px !important;
  letter-spacing: 0.05em;
  padding: 4px 12px !important;
}
.result-more-views[open] > summary {
  background: var(--paper-3);
  color: var(--garnet);
}
.result-more-views-pop {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 30;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 3px;
  padding: 4px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.08);
  display: flex;
  flex-direction: column;
  min-width: 160px;
}
.result-more-views-pop .result-opt {
  text-align: left;
  white-space: nowrap;
}
/* When "By body" is the active group, replace the … chip with a
   visible affordance so users can tell their selection is in there. */
.result-more-views.has-active-child > summary {
  background: var(--garnet);
  color: var(--paper);
}
.result-more-views.has-active-child > summary::after {
  content: " ✓";
  font-size: 11px;
}

/* Copy link to current search */
.copy-link-btn {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  padding: 5px 10px;
}
.copy-link-btn.is-copied {
  background: var(--garnet-soft);
  color: var(--garnet);
  border-color: var(--garnet);
}
.copy-link-glyph {
  font-family: var(--mono);
  font-size: 14px;
  line-height: 1;
}
@media (max-width: 700px) {
  .copy-link-label,
  .export-label { display: none; }
}

/* ─── Export menu ─── */
.export-menu {
  position: relative;
  flex-shrink: 0;
}
.export-menu summary {
  list-style: none;        /* hide native disclosure triangle */
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  padding: 5px 10px;
  cursor: pointer;
  user-select: none;
}
.export-menu summary::-webkit-details-marker { display: none; }
.export-menu[open] summary {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
}
.export-glyph {
  font-family: var(--mono);
  font-size: 14px;
  line-height: 1;
}
.export-pop {
  position: absolute;
  right: 0;
  top: calc(100% + 4px);
  z-index: 20;
  min-width: 220px;
  background: var(--paper);
  border: 1px solid var(--ink);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.10);
  display: flex;
  flex-direction: column;
}
.export-opt {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  padding: 10px 14px;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--rule-soft);
  text-align: left;
  cursor: pointer;
  font-family: var(--body);
  color: var(--ink);
}
.export-opt:last-child { border-bottom: 0; }
.export-opt:hover { background: var(--paper-2); }
.export-opt.is-busy {
  opacity: 0.55;
  cursor: progress;
}
.export-fmt {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--garnet);
}
.export-hint {
  font-family: var(--display);
  font-size: 12px;
  font-style: italic;
  color: var(--ink-3);
}
.searchbar-hint {
  display: flex;
  gap: 10px;
  margin-top: 10px;
  align-items: center;
  flex-wrap: wrap;
}
.searchbar-hint .op {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-3);
  padding: 2px 6px;
  background: var(--paper-3);
  border: 1px solid var(--rule);
}
.searchbar-hint .op-sep {
  color: var(--ink-3);
  opacity: 0.5;
  margin: 0 2px;
}
/* Toggle chip in the operators row — controls whether footnote text is
   indexed alongside body text. Visually distinct from the static .op
   hints because it's an actual interactive control. */
.searchbar-hint .op-toggle {
  font-family: var(--mono);
  font-size: 11px;
  padding: 2px 8px;
  background: var(--paper-2);
  border: 1px solid var(--rule);
  border-radius: 3px;
  cursor: pointer;
  color: var(--ink-2);
  display: inline-flex;
  align-items: center;
  gap: 5px;
  line-height: 1.4;
}
.searchbar-hint .op-toggle:hover {
  border-color: var(--garnet);
}
.searchbar-hint .op-toggle .op-toggle-mark {
  display: inline-block;
  width: 12px;
  text-align: center;
  font-weight: 700;
  color: var(--garnet);
}
.searchbar-hint .op-toggle.is-on {
  background: var(--paper);
  color: var(--ink);
  border-color: var(--garnet);
}
.searchbar-hint .op-toggle:not(.is-on) .op-toggle-mark {
  color: var(--ink-3);
}
.searchbar-hint .op-toggle:not(.is-on) .op-toggle-label {
  color: var(--ink-3);
  text-decoration: line-through;
  text-decoration-thickness: 0.5px;
}
.suggest {
  font-family: var(--display);
  font-size: 13px;
  font-style: italic;
  color: var(--garnet);
  background: transparent;
  border: 0;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 0.5px;
  padding: 2px 0;
}

/* ─────────────  LAYOUT  ─────────────
   v19.43-fix3: the layout is the flex-fill child of section[data-view].
   It takes all remaining viewport height below mast/searchbar/scope,
   and each of its three visible columns gets its own overflow:auto.
   No sticky any more — sticky was a workaround for window-scroll, which
   no longer exists in this app-shell.
   v19.43-fix4: explicit grid-template-rows: minmax(0, 1fr). Without it
   grid creates an implicit auto row whose height = max content height
   (7,000+ result rows), defeating the bounded flex container and
   breaking nested scroll. The single 1fr row consumes all available
   parent height; minmax(0, …) allows it to shrink below content. */
.layout {
  display: grid;
  /* 4-column grid (v15): filters · results · resize-gutter · dossier.
     The 6 px gutter holds a draggable separator that lets the user resize
     the dossier; the variable --col-dossier is updated live during drag. */
  grid-template-columns: var(--col-filters) minmax(0, 1fr) 6px var(--col-dossier);
  grid-template-rows: minmax(0, 1fr);
  flex: 1 1 0;
  min-height: 0;
  overflow: hidden;       /* children handle their own scroll */
}
/* v19.43-fix5: explicit height + min-height on grid items so each
   visible column is a definite-height scroll container in every
   engine. Without this Chrome has been letting overflow:auto resolve
   against an indefinite height in column scenarios. */
.layout > .filters,
.layout > .results,
.layout > .dossier {
  height: 100%;
  min-height: 0;
  max-height: 100%;
}
/* v19.43-fix2: when no paragraph is selected, hide the dossier
   ENTIRELY (column collapses to 0). The result list reclaims the full
   freed horizontal space. The dossier and resize handle reappear the
   moment a paragraph is clicked (state.activeId set → body class
   removed). Keeps the first-paint reading view focused on results. */
body.dossier-collapsed .layout {
  grid-template-columns: var(--col-filters) minmax(0, 1fr) 0 0;
}
body.dossier-collapsed .dossier-resizer,
body.dossier-collapsed .dossier {
  display: none !important;
}
.dossier-rail {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-top: 18px;
}
.dossier-rail .folio.garnet {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  letter-spacing: 0.18em;
  font-size: 9px;
  color: var(--garnet);
  white-space: nowrap;
  margin-top: 12px;
  user-select: none;
}

/* ─────────  v19.43: Welcome card + Tour overlay ───────── */

/* "First visit?" card — appears bottom-right, dismissible.
   v19.43-fix1: stronger visual presence — bigger card, larger garnet
   accent, glowing pulse-shadow that calls attention without screaming.
   The pulse fades after 6 seconds so it doesn't pulse forever. */
.welcome-card {
  position: fixed;
  right: 24px;
  bottom: 24px;
  z-index: 90;
  width: 380px;
  max-width: calc(100vw - 32px);
  padding: 22px 24px 18px;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-top: 6px solid var(--garnet);
  border-radius: 4px;
  box-shadow:
    0 14px 40px rgba(0, 0, 0, 0.18),
    0 2px 8px rgba(0, 0, 0, 0.08),
    0 0 0 1px var(--rule);
  font-family: var(--display);
  animation:
    welcomeFadeIn 0.45s ease-out,
    welcomePulse  2s ease-out 0.5s 3;
}
@keyframes welcomeFadeIn {
  from { opacity: 0; transform: translateY(20px) scale(0.96); }
  to   { opacity: 1; transform: translateY(0)     scale(1);    }
}
@keyframes welcomePulse {
  0%   { box-shadow:
           0 14px 40px rgba(0, 0, 0, 0.18),
           0 2px 8px rgba(0, 0, 0, 0.08),
           0 0 0 1px var(--rule),
           0 0 0 0   rgba(139, 26, 26, 0.45); }
  60%  { box-shadow:
           0 14px 40px rgba(0, 0, 0, 0.18),
           0 2px 8px rgba(0, 0, 0, 0.08),
           0 0 0 1px var(--rule),
           0 0 0 14px rgba(139, 26, 26, 0); }
  100% { box-shadow:
           0 14px 40px rgba(0, 0, 0, 0.18),
           0 2px 8px rgba(0, 0, 0, 0.08),
           0 0 0 1px var(--rule),
           0 0 0 0   rgba(139, 26, 26, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .welcome-card { animation: welcomeFadeIn 0.2s ease-out; }
}
.welcome-card .folio.garnet {
  font-size: 11px;
  letter-spacing: 0.12em;
  font-weight: 700;
}
.welcome-card-lede {
  margin: 10px 0 16px;
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--ink);
}
.welcome-card-actions { display: flex; flex-direction: column; gap: 6px; }
.welcome-card-start,
.welcome-card-skip {
  width: 100%;
  text-align: left;
  padding: 8px 12px;
  font-size: 13px;
}
.welcome-card-start {
  background: var(--garnet);
  color: var(--paper);
  border-color: var(--garnet);
}
.welcome-card-start:hover { background: var(--garnet-2, #6e1414); }
.welcome-card-dismiss {
  position: absolute;
  top: 6px;
  right: 8px;
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  font-size: 18px;
  color: var(--ink-3);
  cursor: pointer;
  line-height: 1;
}
.welcome-card-dismiss:hover { color: var(--garnet); }

/* Tour overlay — backdrop with a transparent cutout (spotlight) and
   a popover positioned next to the highlighted element. */
.tour-overlay {
  position: fixed;
  inset: 0;
  z-index: 100;
  pointer-events: auto;
}
/* The dimmed backdrop is implemented via a giant box-shadow on the
   spotlight div — the cutout is the spotlight rectangle itself, and
   the box-shadow extends outward to cover the whole viewport. */
.tour-spotlight {
  position: absolute;
  border-radius: 4px;
  box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.55);
  pointer-events: none;
  transition: top 0.2s ease, left 0.2s ease, width 0.2s ease, height 0.2s ease;
  outline: 2px solid var(--garnet);
  outline-offset: 2px;
}
.tour-popover {
  position: absolute;
  width: 360px;
  max-width: calc(100vw - 32px);
  padding: 18px 20px 14px;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 3px;
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.18);
  font-family: var(--display);
}
.tour-popover .folio.garnet { font-size: 10px; letter-spacing: 0.1em; }
.tour-popover h3 {
  margin: 6px 0 8px;
  font-size: 18px;
  line-height: 1.25;
}
.tour-popover p {
  margin: 0 0 14px;
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink);
}
.tour-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}
.tour-spacer { flex: 1 1 auto; }
.tour-actions .btn { font-size: 13px; padding: 6px 12px; }
.tour-actions .btn:not(.btn-ghost) {
  background: var(--garnet);
  color: var(--paper);
  border-color: var(--garnet);
}
.tour-actions .btn:not(.btn-ghost):hover { background: var(--garnet-2, #6e1414); }
.tour-actions .btn[disabled] { opacity: 0.4; cursor: not-allowed; }

/* "Tour" button in the masthead nav — small, ghost-style, a touch
   smaller than the regular nav links. */
.mast-tour-btn {
  font-size: 12px;
  padding: 4px 10px;
  margin-left: 6px;
}

/* Resize handle between results and dossier. Invisible by default, shows
   a vertical rule on hover/drag.  Cursor flips to col-resize so it's
   discoverable.  Double-click resets to the default 440 px. */
.dossier-resizer {
  cursor: col-resize;
  background: transparent;
  border-left: 1px solid transparent;
  transition: background-color 0.15s ease, border-color 0.15s ease;
  user-select: none;
  touch-action: none;
}
.dossier-resizer:hover,
.dossier-resizer:focus,
.dossier-resizer.is-dragging {
  background: var(--garnet);
  outline: none;
  opacity: 0.45;
}
body.is-resizing-dossier { cursor: col-resize; user-select: none; }
body.is-resizing-dossier .dossier { pointer-events: none; }
@media (max-width: 980px) {
  /* Stack vertically — no resize handle needed. */
  .layout { grid-template-columns: 1fr; }
  .dossier-resizer { display: none; }
}

/* ─────────────  FILTERS  ─────────────
   v19.43-fix3: not sticky any more — the .layout grid cell already has
   bounded height (it's a flex-fill child of section[data-view]), so
   overflow-y:auto naturally produces a scoped scroll context. */
.filters {
  border-right: 1px solid var(--rule);
  padding: 24px;
  overflow-y: auto;
  min-height: 0;
}
/* v19.44-fix25: the JS-injected mobile filters-toggle pill must be
   hidden on desktop. The button is inserted into the DOM by
   initMobileFilterToggle() regardless of viewport so it can react to
   resize, but it should only become visible at the mobile breakpoint
   (re-displayed inside @media (max-width: 700px)). Without this rule
   it rendered as an unstyled native button at the top of the left
   filter column on desktop. */
.mobile-filters-toggle { display: none; }
.filter-block {
  margin-bottom: 24px;
}
.filter-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 10px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--rule);
}
.filter-head .folio { display: inline; }
.filter-sub {
  margin-top: 14px;
  padding-top: 10px;
  border-top: 1px dotted var(--rule);
}
.filter-sub .folio.sp-section {
  color: var(--preview);
  display: block;
  margin-bottom: 8px;
}

/* ANY / ALL segmented control */
.any-all {
  display: inline-flex;
  border: 1px solid var(--rule);
  background: var(--paper);
  height: 20px;
}
.aa-opt {
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.06em;
  background: transparent;
  border: 0;
  border-right: 1px solid var(--rule);
  padding: 0 8px;
  cursor: pointer;
  color: var(--ink-3);
  line-height: 1;
}
.aa-opt:last-child { border-right: 0; }
.aa-opt:hover { color: var(--ink); }
.aa-opt.is-active {
  background: var(--ink);
  color: var(--paper);
}
.chip-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.chip-grid .chip { font-size: 10px; }
.chip-grid .chip.sp-chip {
  border-color: var(--preview);
  color: var(--preview);
  background: var(--preview-soft);
}
.chip-grid .chip.sp-chip.on {
  background: var(--preview);
  color: var(--paper);
}
.chip-grid .chip.jur-chip {
  border-color: var(--jur-tone);
  color: var(--jur-tone);
  background: var(--jur-soft);
}
.chip-grid .chip.jur-chip.on {
  background: var(--jur-tone);
  color: var(--paper);
}
.chip-grid-compact .chip {
  padding: 2px 7px;
  font-size: 10px;
  font-family: var(--mono);
  letter-spacing: 0.02em;
}
.chip-count {
  margin-left: 6px;
  font-size: 9px;
  color: var(--ink-4);
  font-variant-numeric: tabular-nums;
}
.chip.on .chip-count { color: var(--paper); }
/* v19.43-fix16: zero-hit chip — same convention as the checkbox
   list above. */
.chip.is-zero { opacity: 0.45; }
.chip.is-zero .dim { font-style: italic; }

/* Collapsible filter blocks (details/summary) */
.filter-collapsible summary {
  list-style: none;
  cursor: pointer;
  padding: 4px 0;
  display: flex;
  justify-content: space-between;
  align-items: center;
  user-select: none;
}
.filter-collapsible summary::-webkit-details-marker { display: none; }
.filter-collapsible summary::before {
  content: '▸';
  margin-right: 6px;
  color: var(--ink-4);
  transition: transform 0.15s ease;
  display: inline-block;
}
.filter-collapsible[open] summary::before {
  transform: rotate(90deg);
}
.filter-collapsible[open] summary .folio { color: var(--garnet); }
.filter-block-hint {
  font-size: 10px;
  color: var(--ink-4);
  font-weight: normal;
  margin-left: auto;
}
.filter-search-row {
  margin: 6px 0 8px;
}
.filter-mini-search {
  width: 100%;
  padding: 4px 8px;
  font-size: 11px;
  font-family: var(--mono);
  border: 1px solid var(--rule);
  background: var(--paper);
  color: var(--ink);
  border-radius: 2px;
}
.filter-mini-search:focus {
  outline: 1px solid var(--garnet);
  outline-offset: -1px;
}

/* Status toggle */
.filter-block-status {
  background: var(--paper-2);
  padding: 8px 10px;
  border-radius: 3px;
}
.status-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--display);
  font-size: 12px;
  cursor: pointer;
}
.status-toggle .dim { font-size: 10px; color: var(--ink-4); margin-left: auto; }
.checkbox-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

/* v19.47: scrollable variant for long facet lists (rights-keywords has 119
   values — too many for a flat list, so cap at ~280 px and let it scroll). */
.checkbox-list-scroll {
  max-height: 280px;
  overflow-y: auto;
  padding-right: 4px;        /* room for scrollbar */
}
/* v19.47: typeahead input above a checkbox-list. Mirrors the search-bar
   styling but compact for the rail. */
.filter-typeahead {
  width: 100%;
  margin-bottom: 6px;
  padding: 4px 8px;
  font-family: var(--display);
  font-size: 12px;
  background: var(--paper-2);
  border: 1px solid var(--rule);
  border-radius: 2px;
  color: var(--ink);
}
.filter-typeahead:focus {
  outline: none;
  border-color: var(--garnet);
}
/* v19.50: "Show all (N)" / "Show fewer" toggle below the article-filter
   chip grid. Tiny ghost-link styling — sits below the chips, doesn't
   compete with them visually. */
.filter-toggle-more {
  margin-top: 6px;
  padding: 0;
  background: none;
  border: none;
  color: var(--garnet);
  font-family: var(--display);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
}
.filter-toggle-more:hover {
  text-decoration: underline;
}
.checkbox-list label {
  font-family: var(--display);
  font-size: 13px;
  display: flex;
  gap: 8px;
  align-items: center;
  cursor: pointer;
  color: var(--ink-2);
  padding: 2px 0;
}
.checkbox-list label:hover { color: var(--ink); }
/* v19.43-fix16: visual cue for zero-hit facet values when a query
   or filter is active. Doesn't disable — researcher can still un-
   filter and re-pick — just reads as "this won't get you anything
   right now". */
.checkbox-list label.is-zero { opacity: 0.45; }
.checkbox-list label.is-zero .count { font-style: italic; }
.checkbox-list input[type=checkbox] { accent-color: var(--garnet); }
.checkbox-list .count {
  margin-left: auto;
  font-family: var(--mono);
  font-size: 10px;
  color: var(--ink-4);
  font-feature-settings: "tnum";
}

/* Dual-range slider (years) */
.dual-range {
  position: relative;
  height: 24px;
  margin: 4px 6px 0;
}
.dual-range-track {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 2px;
  background: var(--rule);
  transform: translateY(-50%);
}
.dual-range-fill {
  position: absolute;
  top: 50%;
  height: 2px;
  background: var(--garnet);
  transform: translateY(-50%);
  pointer-events: none;
}
.dual-range-input {
  position: absolute;
  width: 100%;
  height: 24px;
  top: 0;
  left: 0;
  margin: 0;
  background: transparent;
  -webkit-appearance: none;
  appearance: none;
  pointer-events: none;
  outline: none;
}
.dual-range-input-lo { z-index: 2; }
.dual-range-input-hi { z-index: 3; }
.dual-range-input::-webkit-slider-runnable-track {
  background: transparent;
  border: none;
  height: 24px;
}
.dual-range-input::-moz-range-track {
  background: transparent;
  border: none;
  height: 24px;
}
.dual-range-input::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  pointer-events: auto;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--paper);
  border: 2px solid var(--garnet);
  cursor: grab;
  margin-top: -6px;
  box-shadow: 0 1px 2px rgba(0,0,0,0.12);
  transition: transform .12s ease;
}
.dual-range-input::-webkit-slider-thumb:hover { transform: scale(1.15); }
.dual-range-input::-webkit-slider-thumb:active { cursor: grabbing; transform: scale(1.1); }
.dual-range-input::-moz-range-thumb {
  pointer-events: auto;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--paper);
  border: 2px solid var(--garnet);
  cursor: grab;
  box-shadow: 0 1px 2px rgba(0,0,0,0.12);
}
.dual-range-input:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 3px var(--garnet-soft); }
.dual-range-input:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 3px var(--garnet-soft); }
.dual-range-bounds {
  display: flex;
  justify-content: space-between;
  margin: 4px 0 0;
  font-size: 11px;
  color: var(--ink-3);
  font-feature-settings: "tnum";
}

/* ─────────────  RESULTS  ───────────── */
/* v19.43-fix3: results pane is the primary scroll region of the
   app-shell. It fills the centre grid cell vertically; the parent
   .layout has bounded height, so overflow:auto here scopes the
   scroll to this column only. */
.results {
  padding: 28px 40px 80px;
  overflow-y: auto;
  min-height: 0;
}
.results-lede .folio { display: block; }
.results-title {
  font-size: 28px;
  font-weight: 500;
  line-height: 1.1;
  margin: 6px 0 0;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.results-sub {
  font-style: italic;
  color: var(--ink-3);
  margin: 6px 0 0;
  font-size: 14px;
}
.results-tools {
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
  margin: 18px 0 12px;
  padding: 10px 0;
  border-top: 1px solid var(--rule-soft);
}
.result-control {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
/* v19.43-fix2: lightened result-segmented controls. The previous
   "ink-fill" active state was visually too heavy — solid black blocks
   competing with the editorial mast typography. Replaced with a subtle
   paper-3 wash + ink underline rule, matching the rest of the site's
   "newsprint folio" treatment. Border around the cluster is also
   demoted to --rule so the segmented control reads as one cohesive
   sub-toolbar, not a hard frame. */
.result-segmented {
  display: inline-flex;
  border: 1px solid var(--rule);
  background: var(--paper);
}
.result-opt {
  font-family: var(--display);
  font-size: 12px;
  letter-spacing: 0.01em;
  background: transparent;
  color: var(--ink-3);
  border: 0;
  border-right: 1px solid var(--rule);
  padding: 5px 11px;
  cursor: pointer;
  transition: color 120ms ease, background 120ms ease;
}
.result-opt:last-child { border-right: 0; }
.result-opt:hover { background: var(--paper-3); color: var(--ink); }
.result-opt.is-active {
  background: var(--paper-3);
  color: var(--ink);
  box-shadow: inset 0 -2px 0 var(--garnet);
}
.result-opt:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}
.result-opt:disabled:hover {
  background: transparent;
  color: var(--ink-2);
}
.result-actions {
  display: inline-flex;
  gap: 8px;
  margin-left: auto;
  flex-wrap: wrap;
}
.result-tool-btn {
  font-size: 12px;
  padding: 5px 10px;
}
.result-tool-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}
.result-tool-btn:disabled:hover {
  background: transparent;
  color: var(--ink-2);
  border-color: var(--rule);
}
.result-list {
  list-style: none;
  padding: 0;
  margin: 0;
}
.result-list.is-grouped {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.result-doc-group {
  list-style: none;
  border-bottom: 1px solid var(--rule);
}
.result-doc-details > summary {
  list-style: none;
  cursor: pointer;
  display: grid;
  grid-template-columns: 14px 1fr auto;
  gap: 8px 14px;
  align-items: baseline;
  padding: 14px 0;
  user-select: none;
}
.result-doc-details > summary::-webkit-details-marker { display: none; }
.result-doc-details > summary::before {
  content: "▸";
  font-family: var(--mono);
  color: var(--ink-4);
  font-size: 12px;
  transition: transform .12s;
  display: inline-block;
  grid-column: 1;
  grid-row: 1;
}
.result-doc-details[open] > summary::before { transform: rotate(90deg); }
.result-doc-summary-main {
  display: flex;
  align-items: baseline;
  gap: 10px;
  min-width: 0;
  grid-column: 2;
}
.result-doc-summary-title {
  font-family: var(--display);
  font-size: 17px;
  font-style: italic;
  font-weight: 500;
  color: var(--ink);
}
.result-doc-group.sp .result-doc-summary-title { color: var(--ink-2); }
.result-doc-group.jur .result-doc-summary-title { color: var(--jur-tone); }
.result-doc-summary-meta {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
  justify-content: flex-end;
  grid-column: 3;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-3);
}
.result-doc-summary-meta .sig {
  word-break: break-all;
  max-width: 170px;
}
.match-count {
  color: var(--garnet);
  font-feature-settings: "tnum";
}
.relevance-score {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-4);
  font-feature-settings: "tnum";
}
.result-group-list {
  list-style: none;
  margin: 0 0 8px 22px;
  padding: 0;
  border-left: 1px solid var(--rule-soft);
}

/* v16: by-body grouping. Outer level groups treaty bodies / mandates, inner
   level reuses the existing per-document group cards. Visual hierarchy uses
   a slightly heavier border and a sticky header so long body groups stay
   navigable while scrolling through docs. */
.result-body-group { list-style: none; margin-bottom: 24px; }
.result-body-details > summary {
  list-style: none;
  cursor: pointer;
  display: grid;
  grid-template-columns: 24px 1fr auto;
  align-items: baseline;
  gap: 14px;
  padding: 14px 14px 10px;
  background: var(--paper-3);
  border: 1px solid var(--rule);
  border-radius: 4px;
  position: sticky;
  top: var(--mast-h, 96px);
  z-index: 2;
}
.result-body-details > summary::-webkit-details-marker { display: none; }
.result-body-details > summary::before {
  content: '▸';
  color: var(--ink-3);
  transition: transform 0.15s ease;
  display: inline-block;
}
.result-body-details[open] > summary::before { transform: rotate(90deg); }
.result-body-summary-main {
  display: flex;
  align-items: baseline;
  gap: 10px;
  min-width: 0;
}
.result-body-summary-title {
  font-family: var(--display);
  font-weight: 600;
  font-size: 17px;
  color: var(--ink);
  line-height: 1.25;
}
.result-body-group.sp .result-body-summary-title  { color: var(--ink-2); }
.result-body-group.jur .result-body-summary-title { color: var(--jur-tone); }
.result-body-summary-meta {
  display: inline-flex;
  align-items: baseline;
  gap: 12px;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-3);
}
.result-body-inner {
  list-style: none;
  margin: 8px 0 0 0;
  padding: 0 0 0 18px;
  border-left: 2px solid var(--rule-soft);
}
.result-body-inner .result-doc-group { margin-left: 0; }
.result {
  display: grid;
  grid-template-columns: 64px 1fr 130px;
  gap: 24px;
  padding: 22px 0;
  border-bottom: 1px solid var(--rule-soft);
  cursor: pointer;
  transition: background .12s;
}
.result:hover { background: var(--paper-2); }
.result.is-active {
  background: color-mix(in oklch, var(--garnet-soft) 50%, transparent);
  margin: 0 -16px;
  padding-left: 16px;
  padding-right: 16px;
}
.result.is-grouped-result {
  grid-template-columns: 58px 1fr 120px;
  gap: 18px;
  padding: 18px 0 18px 14px;
}
.result.is-grouped-result:last-child { border-bottom: 0; }
.result.sp .result-text { color: var(--sp-tone); }
.result.jur .result-text { color: var(--ink-2); }
.result.jur .result-pn { color: var(--jur-tone); }
.result-margin {
  padding-top: 4px;
  text-align: right;
}
.result-rank {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-4);
}
.result-pn {
  font-family: var(--mono);
  font-size: 22px;
  color: var(--garnet);
  line-height: 1;
  margin-top: 6px;
  font-weight: 500;
}
.result-body { min-width: 0; }
.result-headline {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 6px;
  flex-wrap: wrap;
}
.result-doc {
  font-family: var(--display);
  font-size: 16px;
  font-weight: 500;
  font-style: italic;
  color: var(--ink);
}
.result-spacer {
  flex: 1;
  border-bottom: 1px dotted var(--rule);
  align-self: center;
  min-width: 20px;
}
.result-text {
  font-family: var(--display);
  font-size: 15px;
  line-height: 1.6;
  margin: 0;
  color: var(--ink);
}
.result-text.is-kwic {
  /* KWIC snippets are short by design; no need to fade out the tail. */
  -webkit-mask-image: none;
  mask-image: none;
  font-style: normal;
  background: linear-gradient(to right, transparent 0, var(--paper-2) 6px, var(--paper-2) calc(100% - 6px), transparent 100%);
  padding: 6px 10px;
  border-left: 2px solid var(--garnet);
  margin-left: -10px;
}
.kwic-badge {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.04em;
  color: var(--garnet);
  background: var(--paper-2);
  padding: 1px 6px;
  border-radius: 3px;
  margin-left: auto;
}
/* v19.19: inline expand/collapse toggle below truncated result snippets */
.result-expand-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin: 4px 0 2px;
  padding: 2px 8px 2px 6px;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-3);
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 3px;
  cursor: pointer;
  transition: color 0.12s, border-color 0.12s, background 0.12s;
}
.result-expand-btn:hover {
  color: var(--garnet);
  border-color: var(--garnet);
  background: var(--paper-2);
}
.result-expand-btn.is-expanded {
  color: var(--ink-2);
  border-style: dashed;
}
.result-expand-count {
  color: var(--ink-3);
  font-size: 10px;
}
.result-empty {
  list-style: none;
  padding: 0;
}
.empty-card {
  padding: 28px 24px;
  border: 1px dashed var(--rule);
  border-radius: 4px;
  background: var(--paper-2);
  text-align: left;
}
.empty-card .folio { display: block; margin-bottom: 6px; }
.empty-title {
  font-size: 19px;
  margin: 4px 0 10px;
  color: var(--ink);
  line-height: 1.35;
}
.empty-sub {
  font-size: 14px;
  color: var(--ink-2);
  margin: 0 0 18px;
  line-height: 1.55;
}
.empty-sub code {
  font-family: var(--mono);
  font-size: 12px;
  background: var(--paper);
  padding: 1px 5px;
  border-radius: 2px;
  border: 1px solid var(--rule);
}
.empty-syntax {
  margin: 16px 0 14px;
  padding: 12px 14px;
  background: var(--paper);
  border-left: 2px solid var(--garnet);
}
.empty-syntax .folio { display: block; margin-bottom: 6px; }
.empty-syntax-row {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-2);
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  align-items: center;
}
.empty-syntax-row code {
  font-family: var(--mono);
  font-size: 11px;
  background: var(--paper-2);
  padding: 1px 5px;
  border-radius: 2px;
  border: 1px solid var(--rule);
}
.empty-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
/* v19: synonym suggestions surfaced when the API returns 0 hits. */
.empty-also-try {
  margin: 14px 0 4px;
  padding: 10px 12px;
  background: var(--paper-2);
  border: 1px dashed var(--rule);
  border-radius: 3px;
}
.empty-also-try .folio { display: block; margin-bottom: 6px; }
.empty-also-try-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.empty-also-try-row .btn {
  font-family: var(--display);
  font-style: italic;
  font-size: 13px;
  color: var(--garnet);
}

.result-sentinel {
  list-style: none;
  text-align: center;
  padding: 22px 0;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.05em;
  color: var(--ink-4);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.result-sentinel .dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--garnet);
  display: inline-block;
  animation: pulse 1.2s ease-in-out infinite;
}
.result-sentinel .dot.is-loading {
  /* v19.2: while we're awaiting the next API page, swap the slow pulse
     for a faster, brighter one so the user sees that something is
     happening over the network. */
  animation-duration: 0.6s;
  background: var(--ink);
  box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.06);
}
@keyframes pulse {
  0%, 100% { opacity: 0.3; transform: scale(0.9); }
  50%      { opacity: 1; transform: scale(1.1); }
}
.result-meta {
  display: flex;
  gap: 8px;
  margin-top: 10px;
  flex-wrap: wrap;
  align-items: center;
}
.result-meta .chip.jur-chip {
  border-color: var(--jur-tone);
  color: var(--jur-tone);
  background: var(--jur-soft);
}
.result-aside {
  padding-top: 4px;
  font-size: 11px;
}
.result-aside .folio { display: block; margin-bottom: 4px; }
.result-aside .sig {
  font-family: var(--mono);
  color: var(--ink-3);
  word-break: break-all;
}
/* v19.16: per-row source link. Same restraint as the dossier-sig-link —
   underline-on-hover, tiny ↗ glyph that signals "leaves the app" without
   shouting. Clicks don't flip the active paragraph (handled in the
   row's click delegate; see data-no-dossier). */
.result-aside .sig-link {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px dotted transparent;
}
.result-aside .sig-link:hover {
  color: var(--garnet);
  border-bottom-color: var(--garnet);
}
.result-aside .sig-arrow {
  font-size: 9px;
  opacity: 0.7;
  margin-left: 1px;
}

.result-more {
  margin-top: 24px;
  text-align: center;
  font-family: var(--display);
  font-style: italic;
  color: var(--ink-3);
  font-size: 14px;
}

/* ─────────────  DOSSIER (right panel)  ─────────────
   v19.43-fix3: not sticky any more (see .filters comment).
   v19.43-fix8: app-shell drawer pattern. .dossier itself is a flex
   column with header (top) + body (scrollable middle) + footer
   (bottom). Replaces the old single-scroll panel where the close
   button collided with S/M/L and the 7-button toolbar lived at the
   end of the scroll (so it disappeared the moment users scrolled). */
.dossier {
  border-left: 1px solid var(--rule);
  background: var(--paper-2);
  padding: 0;
  overflow: hidden;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.dossier-header {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 20px;
  border-bottom: 1px solid var(--rule);
  background: var(--paper-2);
}
.dossier-header-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  min-width: 0;
}
.dossier-kind {
  letter-spacing: 0.06em;
}
.dossier-body {
  flex: 1 1 0;
  min-height: 0;
  overflow-y: auto;
  padding: 20px 24px 28px;
}
.dossier-footer {
  flex: 0 0 auto;
  display: flex;
  align-items: stretch;
  gap: 6px;
  padding: 10px 14px;
  border-top: 1px solid var(--rule);
  background: var(--paper);
  position: relative;     /* anchor for cite-pop / more-pop */
}

/* v19.43-fix8: × close button — quiet ghost glyph, no border, sits
   on the right of the header. Replaces the old absolute-positioned
   bordered button that collided with S/M/L. */
.dossier-close {
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  border: 0;
  background: transparent;
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  border-radius: 2px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background .12s, color .12s;
}
.dossier-close:hover,
.dossier-close:focus-visible {
  background: var(--paper-3);
  color: var(--garnet);
  outline: none;
}

/* v19.43-fix10: subtler Cite CTA. Outline-garnet by default (no
   solid fill); slimmer padding and smaller font. Hover fills with
   garnet so the action remains discoverable. Visually quieter than
   the original solid CTA but still reads as primary because of the
   accent colour and the format chip. */
.dossier-cta {
  flex: 1 1 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 5px 10px;
  background: transparent;
  border: 1px solid var(--garnet);
  color: var(--garnet);
  font-family: var(--display);
  font-size: 12px;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: background .12s, color .12s, border-color .12s;
}
.dossier-cta:hover,
.dossier-cta:focus-visible {
  background: var(--garnet);
  color: var(--paper);
  outline: none;
}
.dossier-cta-icon { font-style: italic; font-size: 14px; line-height: 1; }
.dossier-cta-label { font-weight: 500; }
.dossier-cta-fmt {
  font-family: var(--mono);
  font-size: 9px;
  padding: 2px 5px;
  background: var(--garnet-soft, #f5e9e9);
  border-radius: 2px;
  letter-spacing: 0.04em;
  color: var(--garnet);
  transition: background .12s, color .12s;
}
.dossier-cta:hover .dossier-cta-fmt,
.dossier-cta:focus-visible .dossier-cta-fmt {
  background: rgba(255,255,255,0.18);
  color: var(--paper);
}
.dossier-cta.is-flash {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
}
.dossier-cta.is-flash .dossier-cta-fmt {
  background: rgba(255,255,255,0.2);
  color: var(--paper);
}

/* v19.43-fix8: secondary icon buttons (Save / Note / Permalink) +
   the More menu summary. Square 36x36, ghost style, no label. */
.dossier-icon-btn {
  flex: 0 0 36px;
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid var(--rule);
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  transition: background .12s, color .12s, border-color .12s;
  list-style: none;
  user-select: none;
}
.dossier-icon-btn::-webkit-details-marker { display: none; }
.dossier-icon-btn:hover {
  background: var(--paper-3);
  color: var(--garnet);
  border-color: var(--ink-3);
}
.dossier-icon-btn.on {
  background: var(--paper-3);
  color: var(--garnet);
  border-color: var(--garnet);
}
.dossier-icon-btn.is-flash {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
}

/* More menu popover — anchored above the toolbar, opens upward so
   it doesn't get clipped by the bounded drawer footer. */
.dossier-more {
  position: relative;
}
.dossier-more-summary {
  cursor: pointer;
}
.dossier-more[open] .dossier-more-summary {
  background: var(--paper-3);
  color: var(--ink);
  border-color: var(--ink-3);
}
.dossier-more-pop {
  position: absolute;
  bottom: calc(100% + 6px);
  right: 0;
  min-width: 240px;
  background: var(--paper);
  border: 1px solid var(--ink);
  box-shadow: 0 8px 24px rgba(0,0,0,0.08);
  padding: 6px 0;
  z-index: 30;
}
.dossier-more-opt {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  background: transparent;
  border: 0;
  padding: 9px 16px;
  font-family: var(--body);
  font-size: 13px;
  color: var(--ink);
  text-align: left;
  cursor: pointer;
  transition: background .1s;
}
.dossier-more-opt:hover { background: var(--paper-3); }
.dossier-more-opt-quiet { color: var(--ink-3); }
.dossier-more-icon {
  font-family: var(--mono);
  font-size: 14px;
  width: 18px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-3);
}
.dossier-more-rule {
  border: 0;
  border-top: 1px solid var(--rule);
  margin: 6px 0;
}
.dossier-more-display {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 16px;
}
.dossier-more-display .folio { font-size: 10px; color: var(--ink-3); flex: 0 0 auto; }
.dossier-more-display .dossier-font-controls {
  margin: 0;
}

/* v19.43-fix8: cite popover repositioned to anchor on the footer's
   "More" trigger. Opens upward (bottom-positioned) so it doesn't
   get clipped at the bottom of the drawer. */
.dossier-footer .cite-pop {
  position: absolute;
  bottom: calc(100% + 6px);
  right: 14px;
  min-width: 280px;
  z-index: 31;
}
.dossier-empty {
  color: var(--ink-3);
}
.dossier-empty .folio { display: block; margin-bottom: 8px; }
.dossier-title {
  font-family: var(--display);
  font-size: 20px;
  font-weight: 500;
  line-height: 1.2;
  margin: 6px 0 0;
  font-style: italic;
  color: var(--ink);
}
.dossier-sig {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-4);
  margin-top: 4px;
}
/* v19.16: the doc-symbol is now the source link itself (replaces the
   standalone bottom .dossier-original line). Underline-on-hover so it
   reads as link without making the every-paragraph header visually loud. */
.dossier-sig-link {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px dotted transparent;
}
.dossier-sig-link:hover {
  color: var(--garnet);
  border-bottom-color: var(--garnet);
}
.dossier-sig-arrow {
  font-size: 10px;
  opacity: 0.7;
  margin-left: 1px;
}
.dossier-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  margin-top: 16px;
  padding: 14px 0;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}
.dossier-dp .folio { display: block; }
.dossier-dp .v {
  font-family: var(--display);
  font-size: 13px;
  color: var(--ink);
  margin-top: 2px;
  word-break: break-word;
}
.dossier-dp .v.accent { color: var(--garnet); }
.dossier-dp-wide { grid-column: 1 / -1; }    /* span both grid columns */
.dossier-chip {
  display: inline-block;
  padding: 1px 7px;
  margin: 0 4px 4px 0;
  background: var(--paper-2);
  border: 1px solid var(--rule);
  border-radius: 3px;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-2);
}
.dossier-chip-soft {
  font-family: var(--display);
  font-size: 12px;
  letter-spacing: 0;
  color: var(--ink);
  background: var(--paper-3, #f0e9e1);
}
/* v19.43-fix8: .dossier-folio-row + the absolute-positioned close
   button were superseded by .dossier-header. Old rules removed. */
.dossier-country {
  color: var(--ink-2);
  font-style: italic;
}
.dossier-rep {
  color: var(--ink-3);
  font-size: 0.92em;
  font-style: italic;
}

/* JUR outcome badge — colour-codes the case disposition in the dossier
   folio so users see "Violation found" / "Inadmissible" before the title. */
.outcome-badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 3px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border: 1px solid currentColor;
  background: transparent;
}
.outcome-violation_found {
  color: #b22222;       /* firebrick — substantive finding against the State */
  background: #fdf2f2;
  border-color: #b22222;
}
.outcome-merits_no_violation {
  color: #2c6e3a;       /* dark green — merits, no violation */
  background: #f1f8f3;
  border-color: #2c6e3a;
}
.outcome-inadmissible {
  color: #6b6058;       /* sand — procedural exit */
  background: #f6f1ec;
  border-color: #b9ad9d;
}
.outcome-discontinued {
  color: #6b6058;
  background: #f6f1ec;
  border-color: #b9ad9d;
  text-decoration: line-through;
}
.outcome-views {
  color: #4a5d8a;       /* indigo — substantive deliberation, no specific outcome label */
  background: #f0f3fa;
  border-color: #4a5d8a;
}
.outcome-decision {
  color: #4a5d8a;
  background: #f0f3fa;
  border-color: #4a5d8a;
}
.outcome-other {
  color: var(--ink-3);
  background: var(--paper-2);
  border-color: var(--rule);
}

/* JUR metadata-confidence pill — sits next to the outcome badge in the
   dossier folio. Only shown for medium/low confidence (or PDF/OCR
   provenance) so high-confidence cases stay visually quiet. */
.meta-confidence-pill {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 3px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border: 1px solid currentColor;
  cursor: help;
}
.meta-confidence-low {
  color: #8a4a00;
  background: #fdf6ee;
  border-color: #c98e3f;
}
.meta-confidence-medium {
  color: #6b6058;
  background: #f6f1ec;
  border-color: #b9ad9d;
}

/* Metadata-quality feedback — anonymous thumb up/down strip under the
   dossier grid. Low-effort, no form, optional one-line note on thumbs-down. */
.meta-feedback {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 12px;
  padding: 8px 0;
  border-top: 1px dashed var(--rule);
  font-size: 11px;
  color: var(--ink-3);
  font-family: var(--mono);
  letter-spacing: 0.04em;
}
.meta-feedback-prompt { text-transform: uppercase; }
.meta-feedback-btn {
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 3px;
  padding: 2px 8px;
  font-family: var(--mono);
  font-size: 12px;
  cursor: pointer;
  color: var(--ink-2);
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.meta-feedback-btn:hover { border-color: var(--ink-2); color: var(--ink); }
.meta-feedback-btn.is-flash {
  background: var(--garnet);
  color: var(--paper);
  border-color: var(--garnet);
}
.meta-feedback-thanks { font-style: italic; }
.dossier-abstract {
  margin: 14px 0 0;
  padding: 10px 14px;
  background: var(--paper-2);
  border-left: 2px solid var(--garnet);
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink-2);
}
.dossier-abstract .folio {
  font-size: 10px;
  letter-spacing: 0.08em;
  color: var(--ink-4);
  margin-bottom: 4px;
}
.dossier-abstract p { margin: 0; }
.docs-status {
  display: inline-block;
  margin-left: 8px;
  padding: 0 6px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.05em;
  border-radius: 2px;
  text-transform: uppercase;
  vertical-align: middle;
}
.docs-status.superseded {
  background: var(--paper-3, #f0e9e1);
  color: var(--ink-4);
  text-decoration: line-through;
}
.docs-status.revised {
  background: var(--garnet-soft, #f5e9e9);
  color: var(--garnet);
}

/* v19.43-fix7: context-aware quote block.
   Surrounding paragraphs (.dossier-context-para, no -active) are
   dimmed prose without any bar; the active paragraph keeps the
   garnet rule + italic display face it always had. Click on a
   context paragraph promotes it to active (handled in JS). */
.dossier-context {
  margin: 16px 0 0;
}
.dossier-context-section {
  font-size: 10px;
  color: var(--ink-3);
  margin-bottom: 10px;
  letter-spacing: 0.06em;
  line-height: 1.4;
}
.dossier-context-section .dossier-bc-seg { color: var(--garnet); }
.dossier-context-section .dossier-bc-sep {
  color: var(--ink-4);
  margin: 0 6px;
}
.dossier-context-para {
  display: block;
  padding: 10px 0 10px 14px;
  border-left: 2px solid transparent;
  cursor: pointer;
  transition: background .12s ease, border-color .12s ease;
}
.dossier-context-para:hover {
  background: var(--paper-3);
  border-left-color: var(--rule);
}
.dossier-context-para .dossier-context-num {
  font-size: 10px;
  color: var(--ink-4);
  display: block;
  margin-bottom: 3px;
}
.dossier-context-prose {
  font-family: var(--body);
  font-size: calc(13px * var(--dossier-font, 1));
  color: var(--ink-3);
  line-height: 1.55;
  margin: 0;
}
/* The active paragraph: garnet rule, italic display face, full
   weight. Inherits the original .dossier blockquote styling. */
.dossier-context-active {
  padding: 0;
  cursor: default;
  border-left: 0;
  background: transparent;
}
.dossier-context-active:hover {
  background: transparent;
  border-left-color: transparent;
}
.dossier-context-active blockquote {
  margin: 6px 0;
  padding-left: 14px;
  border-left: 2px solid var(--garnet);
  color: var(--ink-2);
  background: var(--paper-3);
  padding-top: 12px;
  padding-bottom: 12px;
  padding-right: 12px;
}
.dossier-expand-section {
  display: inline-block;
  margin: 14px 0 0;
  padding: 6px 12px;
  background: transparent;
  border: 1px solid var(--rule);
  color: var(--ink-3);
  font-family: var(--display);
  font-size: 11px;
  letter-spacing: 0.06em;
  cursor: pointer;
  transition: background .12s, color .12s, border-color .12s;
}
.dossier-expand-section:hover {
  background: var(--paper-3);
  color: var(--garnet);
  border-color: var(--garnet-edge);
}

.dossier blockquote {
  margin: 16px 0 0;
  padding-left: 14px;
  border-left: 2px solid var(--garnet);
  color: var(--ink-2);
}
.dossier blockquote .pn {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--garnet);
  margin-bottom: 4px;
  display: block;
}
.dossier blockquote p {
  font-family: var(--display);
  /* v15: scaled by --dossier-font (0.9 / 1 / 1.15) via S/M/L control */
  font-size: calc(14px * var(--dossier-font, 1));
  font-style: italic;
  line-height: 1.55;
  margin: 0;
}
.dossier-title { font-size: calc(20px * var(--dossier-font, 1)); }
.dossier blockquote .pn { font-size: calc(11px * var(--dossier-font, 1)); }
.dossier-dp .v          { font-size: calc(13px * var(--dossier-font, 1)); }

/* v15: tiny S/M/L cluster.
   v19.43-fix10: lives in the .dossier-header now (between the kind
   folio and ×). Even smaller: 10 px font, 2 px vertical padding, so
   it doesn't compete visually with × or the GENERAL COMMENT folio. */
.dossier-font-controls {
  display: inline-flex;
  align-items: center;
  gap: 0;
  flex: 0 0 auto;
  border: 1px solid var(--rule);
  border-radius: 3px;
  overflow: hidden;
}
.dossier-font-controls button {
  border: 0;
  background: transparent;
  padding: 2px 7px;
  font-family: var(--mono);
  font-size: 10px;
  line-height: 1.4;
  cursor: pointer;
  color: var(--ink-3);
  letter-spacing: 0.04em;
}
.dossier-font-controls button + button { border-left: 1px solid var(--rule); }
.dossier-font-controls button:hover { background: var(--paper-3); color: var(--ink); }
.dossier-font-controls button.is-active {
  background: var(--ink);
  color: var(--paper);
}
/* v19.43-fix8: .dossier-folio-row removed (replaced by .dossier-header). */

/* v18: unified dossier toolbar — replaces the old two-row layout
   (dossier-workspace + dossier-actions) with one flex strip of equal-
   width icon buttons. Cite menu is now a popover anchored to its
   button rather than pushing the layout, so the toolbar height stays
   stable when the menu opens. */
.dossier-actions { display: none; }     /* legacy, kept for safety */
.cite-opt {
  display: flex;
  flex-direction: row;
  align-items: baseline;
  gap: 10px;
  padding: 9px 14px;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--rule-soft, var(--rule));
  text-align: left;
  cursor: pointer;
  font-family: var(--body);
  color: var(--ink);
}
.cite-opt:last-child { border-bottom: 0; }
.cite-opt:hover { background: var(--paper-2); }
.cite-fmt {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  color: var(--garnet);
  font-weight: 600;
  min-width: 56px;
}
.cite-name {
  font-size: 13px;
  color: var(--ink);
}

/* ─── Reading mode (A3) ─── */
.reading-mode-btn { font-size: 12px; padding: 5px 10px; }
.reading-mode-btn.is-active {
  background: var(--garnet-soft, #f5e9e9);
  color: var(--garnet);
  border-color: var(--garnet);
}
@media (max-width: 700px) {
  .cite-label, .reading-mode-label { display: none; }
}
/* Reading mode (B/v13 redesign) — collapse rail + result list, hand the
   centre stage to a single reading column. The dossier becomes the page.
   Goal: no UI clutter, body-text-width column, larger font, comfortable
   line-height. The user just wants to read the active paragraph + its
   document context. Search bar + scope tabs stay visible (so they can
   exit or navigate without leaving reading mode). */
body.is-reading-mode .scope-banner,
body.is-reading-mode .filters,
body.is-reading-mode .results,
body.is-reading-mode .results-tools,
body.is-reading-mode .results-lede {
  display: none !important;
}
body.is-reading-mode .layout {
  grid-template-columns: 1fr;             /* single-column page */
}
body.is-reading-mode .dossier {
  max-width: 760px;                       /* reading-comfortable column */
  margin: 0 auto;
  padding: 32px 40px 80px;
  border-left: 0;                         /* drop the side gutter */
  background: var(--paper);
}
body.is-reading-mode .dossier-empty {
  text-align: center;
  padding: 80px 20px;
}
body.is-reading-mode .dossier-header-meta,
body.is-reading-mode .dossier-title,
body.is-reading-mode .dossier-sig {
  text-align: left;
}
body.is-reading-mode .dossier-title {
  font-size: 26px;
  line-height: 1.25;
  margin: 6px 0 4px;
}
body.is-reading-mode .dossier-sig { font-size: 14px; margin-bottom: 18px; }
body.is-reading-mode .dossier-grid {
  grid-template-columns: 1fr 1fr 1fr 1fr; /* compact metadata band, 4-up */
  gap: 16px 24px;
  padding: 14px 0;
  margin: 0 0 24px;
}
body.is-reading-mode .dossier-dp-wide { grid-column: 1 / -1; }
body.is-reading-mode .dossier blockquote {
  margin: 24px 0;
  padding: 14px 20px 14px 22px;
  border-left: 3px solid var(--garnet);
  background: var(--paper-2);
}
body.is-reading-mode .dossier blockquote .pn {
  font-size: 14px;
  letter-spacing: 0.04em;
  display: block;
  margin-bottom: 10px;
  color: var(--garnet);
}
body.is-reading-mode .dossier blockquote p {
  font-size: 18px;
  line-height: 1.85;
  color: var(--ink);
}
body.is-reading-mode .dossier-toolbar {
  margin-top: 32px;
  padding: 12px;
  border-top: 1px solid var(--rule);
}
@media (max-width: 700px) {
  body.is-reading-mode .dossier { padding: 22px 20px 60px; }
  body.is-reading-mode .dossier-grid { grid-template-columns: 1fr 1fr; }
}
/* Sticky "Exit reading" affordance — top-right above the dossier so
   it's always reachable without scrolling. */
body.is-reading-mode .reading-mode-btn {
  position: fixed;
  top: 56px;                      /* below the prominent top bar */
  right: 16px;
  z-index: 49;
  background: var(--paper);
  border: 1px solid var(--garnet);
  color: var(--garnet);
  box-shadow: 0 4px 14px rgba(0,0,0,.08);
}

/* v16: full-width "you are in reading mode" banner. Sits at top of viewport,
   click anywhere on it to exit. The kbd hints make Esc/R discoverable so
   power users don't have to mouse-target every time. */
.reading-mode-bar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 10px 16px;
  background: var(--garnet);
  color: var(--paper);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.04em;
  cursor: pointer;
  user-select: none;
  box-shadow: 0 2px 8px rgba(0,0,0,.18);
  text-align: center;
}
.reading-mode-bar:hover { filter: brightness(1.06); }
.reading-mode-bar-icon  { font-size: 14px; }
.reading-mode-bar-label { font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em; }
.reading-mode-bar-hint  { color: rgba(255,255,255,.85); }
.reading-mode-bar-hint kbd {
  display: inline-block;
  padding: 1px 6px;
  margin: 0 2px;
  border: 1px solid rgba(255,255,255,.55);
  border-radius: 3px;
  font-family: var(--mono);
  font-size: 11px;
  background: rgba(255,255,255,.08);
  color: var(--paper);
}
.reading-mode-bar-close {
  font-size: 18px;
  line-height: 1;
  margin-left: 4px;
  opacity: 0.85;
}
/* Push the dossier down so the bar doesn't cover the title. */
body.is-reading-mode .dossier { padding-top: 64px; }

/* ─────────────  FOOTER  ─────────────
   v19.43-fix6: drop margin-top:40px. In the old window-scroll layout
   that gave the foot room to breathe after long pages of results;
   in app-shell the page never scrolls, so this margin is just 40 px
   of dead viewport space below the bounded results pane. */
.foot {
  border-top: 1px solid var(--ink);
  background: var(--paper-2);
  flex: 0 0 auto;
}
/* v19.43-fix9: tighter footer. 16→6 px vertical padding, body font
   from 13→11 px, link font from 13→11 px. Recovers ~26 px of
   viewport for the results pane. The folio "BUILD …" + colophon
   line remains readable but stops eating premium real estate. */
.foot-inner {
  padding: 6px 40px;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  font-size: 11px;
}
.foot-link {
  font-size: 11px;
  font-style: italic;
  color: var(--garnet);
  text-decoration: none;
  border-bottom: 0.5px solid var(--garnet-edge);
}
.foot-link:hover { border-bottom-color: var(--garnet); }
/* v19.3: keep the report link visually identical to the GitHub link
   even though it's a <button>. */
.foot-report-btn {
  background: transparent;
  border: 0;
  border-bottom: 0.5px solid var(--garnet-edge);
  cursor: pointer;
  font-family: var(--display);
  font-size: 11px;
  padding: 0;
}

/* ─────────────  LOADER  ───────────── */
.loader {
  position: fixed;
  inset: 0;
  background: var(--paper);
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity .25s ease;
}
.loader.hidden {
  opacity: 0;
  pointer-events: none;
}
.loader-inner {
  text-align: center;
}
.loader-inner .folio { color: var(--garnet); margin-bottom: 12px; display: block; }
.loader-bar {
  width: 240px;
  height: 2px;
  background: var(--rule);
  margin: 0 auto 12px;
  position: relative;
  overflow: hidden;
}
.loader-fill {
  position: absolute;
  top: 0; left: 0;
  height: 100%;
  width: 0;
  background: var(--garnet);
  transition: width .3s ease;
}
#loader-msg {
  font-size: 11px;
  color: var(--ink-3);
}

/* ─────────────  VIEW ROUTING  ─────────────
   v19.43-fix6: the active view is shown as `display: flex` (was
   `display: block`). The app-shell layout up top defines section
   [data-view] as a flex column container; the previous block override
   here was higher-specificity and silently neutered the whole flex
   chain — section.height collapsed to content (6000+ px) and main.layout
   never got bounded, so nothing inside scrolled. */
section[data-view] { display: none; }
body[data-active-view="search"]    section[data-view="search"]    { display: flex; }
body[data-active-view="documents"] section[data-view="documents"] { display: flex; }
body[data-active-view="workspace"] section[data-view="workspace"] { display: block; }
body[data-active-view="about"]     section[data-view="about"]     { display: block; }

/* ─────────────  DOCUMENTS VIEW  ───────────── */
.docs-mast {
  border-bottom: 1px solid var(--rule);
  background: var(--paper);
  flex: 0 0 auto;
}
.docs-mast-inner {
  max-width: 1280px;
  margin: 0 auto;
  padding: 26px 40px 22px;
}
.docs-title {
  font-size: 28px;
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: 1.1;
  margin: 6px 0 0;
  color: var(--ink);
}
.docs-sub {
  font-style: italic;
  color: var(--ink-3);
  margin: 6px 0 0;
  font-size: 14px;
}

.docs-tools {
  border-bottom: 1px solid var(--rule);
  background: var(--paper-2);
}
.docs-tools {
  display: flex;
  gap: 16px;
  align-items: center;
  flex-wrap: wrap;
  padding: 14px 40px;
  max-width: 1280px;
  margin: 0 auto;
}
.docs-filter {
  flex: 1;
  min-width: 220px;
  font-family: var(--display);
  font-size: 16px;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--ink-3);
  color: var(--ink);
  outline: none;
  padding: 6px 0;
}
.docs-filter:focus { border-bottom-color: var(--garnet); }
.docs-filter::placeholder { color: var(--ink-4); font-style: italic; }

/* v19.49: 3-tab scope selector (GC / JUR / SP — "All" dropped). Tabs
   stretch full rail width and split equally. The full label
   ("General Comments") shows when there's room; the rail is narrow on
   the typical 1440 px viewport so we collapse to the abbreviation
   below ~360 px of available scope row. */
.docs-scope {
  display: flex;
  width: 100%;
  border: 1px solid var(--ink);
  font-family: var(--display);
  font-size: 12px;
}
.docs-scope-opt {
  flex: 1 1 0;
  min-width: 0;
  background: transparent;
  color: var(--ink-2);
  border: 0;
  border-right: 1px solid var(--ink);
  padding: 6px 8px;
  cursor: pointer;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.docs-scope-opt:last-child { border-right: 0; }
.docs-scope-opt:hover { background: var(--paper-3); color: var(--ink); }
.docs-scope-opt.is-active { background: var(--ink); color: var(--paper); }
/* Default: show abbreviations (the rail is typically too narrow for the
   full labels to fit without truncation). Promote to full labels only
   on viewports where the rail has room — empirically that's > 1500 px,
   beyond which the layout has space to widen the rail. */
.docs-scope-full { display: none; }
.docs-scope-abbr { display: inline; font-family: var(--mono); letter-spacing: 0.04em; }
@media (min-width: 1500px) {
  .docs-scope-full { display: inline; font-family: var(--display); }
  .docs-scope-abbr { display: none; }
}

.docs-body {
  max-width: 1280px;
  margin: 0 auto;
  padding: 28px 40px 80px;
}

.docs-section-head {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--garnet);
  margin: 32px 0 8px;
  padding-bottom: 6px;
  border-bottom: 3px double var(--rule);
}
.docs-section-head:first-child { margin-top: 0; }
.docs-section-head.jur-section-head { color: var(--jur-tone); }
.docs-section-head.sp-section-head { color: var(--preview); }

.docs-committee {
  margin-bottom: 18px;
}
.docs-committee > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: baseline;
  gap: 14px;
  padding: 10px 0;
  border-bottom: 1px solid var(--rule);
  user-select: none;
}
.docs-committee > summary::-webkit-details-marker { display: none; }
.docs-committee > summary::before {
  content: "▸";
  font-family: var(--mono);
  color: var(--ink-4);
  font-size: 12px;
  transition: transform .12s;
  display: inline-block;
}
.docs-committee[open] > summary::before { transform: rotate(90deg); }
.docs-committee-name {
  font-family: var(--display);
  font-size: 18px;
  font-weight: 500;
  color: var(--ink);
}
.docs-committee.jur .docs-committee-name { color: var(--jur-tone); }
.docs-committee.sp .docs-committee-name { color: var(--ink-2); }
.docs-committee-count {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-4);
  margin-left: auto;
}

.docs-list {
  list-style: none;
  padding: 0;
  margin: 8px 0 0;
}
.docs-row {
  display: grid;
  grid-template-columns: 140px 1fr 70px 80px 28px;
  gap: 18px;
  align-items: baseline;
  padding: 10px 6px;
  border-bottom: 1px solid var(--rule-soft);
  cursor: pointer;
  text-decoration: none;
  color: inherit;
  transition: background .12s;
}
.docs-row:hover { background: var(--paper-2); }
.docs-row .sig {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-3);
  word-break: break-all;
}
.docs-row .name {
  font-family: var(--display);
  font-size: 15px;
  color: var(--ink);
  font-style: italic;
}
.docs-row.jur .name { color: var(--jur-tone); }
.docs-row.sp .name { color: var(--ink-2); }
.docs-row .year {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink-3);
  font-feature-settings: "tnum";
  text-align: right;
}
.docs-row .pcount {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--garnet);
  text-align: right;
  font-feature-settings: "tnum";
}
.docs-row .arrow {
  font-family: var(--mono);
  color: var(--ink-4);
  text-align: right;
  font-size: 14px;
}
.docs-row:hover .arrow { color: var(--garnet); }

.docs-empty {
  padding: 60px 0;
  text-align: center;
  font-family: var(--display);
  font-style: italic;
  color: var(--ink-3);
}

/* ─────────────  DOCUMENTS VIEW · 3-PANE READER (v17)  ─────────────
   Layout:  rail (260px)  ·  centre (1fr)  ·  drawer (320px / collapsed 32px)
   On <980px viewports the rail moves above the body and the drawer hides. */
/* v19.43-fix3: docs-reader is the flex-fill child of section[data-view="documents"].
   Its grid children each scroll internally; the docs-mast above it stays
   at the top of the section in normal flow.
   v19.43-fix4: explicit single-row track (minmax(0, 1fr)) so the grid
   row consumes parent height instead of expanding to content. */
/* v19.43-fix16: variant-C layout — drop the 1600 px max-width.
   Side panes grow proportionally on wide monitors (rail to ~22%,
   outline to ~24%) while the centre body stays full‑width as a
   grid cell — the actual reading column inside it is constrained
   to ~720 px by `.docs-reader-body article` max-width. Eliminates
   the 392 px outer gutters at 1992 px viewport without giving up
   the 65–75 char reading line length. */
.docs-reader {
  display: grid;
  grid-template-columns: minmax(260px, 22%) minmax(0, 1fr) minmax(300px, 24%);
  grid-template-rows: minmax(0, 1fr);
  gap: 0;
  margin: 0;
  width: 100%;
  flex: 1 1 0;
  min-height: 0;
  overflow: hidden;
}
.docs-reader > .docs-rail,
.docs-reader > .docs-reader-body,
.docs-reader > .docs-drawer {
  height: 100%;
  min-height: 0;
  max-height: 100%;
}
.docs-reader > .docs-rail        { border-right: 1px solid var(--rule); background: var(--paper-2); }
.docs-reader > .docs-reader-body { background: var(--paper); }
.docs-reader > .docs-drawer      { border-left: 1px solid var(--rule); background: var(--paper-2); }
.docs-reader > .docs-drawer.is-collapsed { width: 32px; }

@media (max-width: 1100px) {
  .docs-reader { grid-template-columns: 240px minmax(0, 1fr); }
  .docs-reader > .docs-drawer { display: none; }
}
@media (max-width: 760px) {
  .docs-reader { grid-template-columns: 1fr; }
  .docs-reader > .docs-rail { border-right: 0; border-bottom: 1px solid var(--rule); max-height: 220px; overflow-y: auto; }
}

/* RAIL ───────────────────────────────────────────────────────
   v19.43-fix3: not sticky — docs-reader has bounded height and the
   rail is a grid column with overflow:auto. */
.docs-rail {
  overflow-y: auto;
  padding: 0;
  min-height: 0;
}
.docs-rail-tools {
  position: sticky;
  top: 0;
  background: var(--paper-2);
  border-bottom: 1px solid var(--rule);
  padding: 12px 14px;
  z-index: 2;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.docs-rail-tools .docs-filter { font-size: 13px; padding: 5px 0; }
.docs-rail-tools .docs-scope  { font-size: 11px; }
.docs-rail-tools .docs-scope-opt { padding: 4px 10px; font-size: 11px; font-family: var(--mono); }

.docs-rail-list { padding: 6px 0 80px; }
.docs-rail-empty {
  padding: 30px 16px;
  font-style: italic;
  color: var(--ink-3);
  font-size: 13px;
  text-align: center;
}
.docs-rail-section {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--garnet);
  padding: 14px 14px 4px;
}
.docs-rail-section.jur { color: var(--jur-tone); }
.docs-rail-section.sp  { color: var(--preview); }

.docs-rail-committee { padding: 0; }
.docs-rail-committee > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: 6px 14px;
  font-size: 12px;
  color: var(--ink-2);
  user-select: none;
}
.docs-rail-committee > summary::-webkit-details-marker { display: none; }
.docs-rail-committee > summary::before {
  content: "▸";
  margin-right: 6px;
  font-family: var(--mono);
  color: var(--ink-4);
  transition: transform .12s;
  display: inline-block;
}
.docs-rail-committee[open] > summary::before { transform: rotate(90deg); }
.docs-rail-committee-name  { font-weight: 600; color: var(--ink); flex: 1; }
.docs-rail-committee-count { font-family: var(--mono); font-size: 10px; color: var(--ink-4); }
.docs-rail-rows { padding: 0; }

.docs-rail-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2px;
  padding: 8px 14px 8px 28px;
  border-left: 2px solid transparent;
  text-decoration: none;
  color: var(--ink);
  font-size: 12px;
  line-height: 1.35;
}
.docs-rail-row:hover { background: var(--paper-3); }
.docs-rail-row.is-active {
  background: var(--paper);
  border-left-color: var(--garnet);
}
.docs-rail-row.is-active .docs-rail-row-title { color: var(--garnet); font-weight: 600; }
.docs-rail-row-sig   { font-size: 10px; color: var(--ink-3); }
.docs-rail-row-title { font-family: var(--display); font-size: 13px; }
.docs-rail-row.jur .docs-rail-row-title { color: var(--jur-tone); }
.docs-rail-row.sp  .docs-rail-row-title { color: var(--ink-2); }
.docs-rail-row-meta  { font-size: 10px; color: var(--ink-4); }

/* CENTRE: document body ──────────────────────────────────────── */
.docs-reader-body {
  padding: 24px 56px 80px;
  overflow-y: auto;
  min-height: 0;
  scroll-padding-top: 80px;
}
/* v19.43-fix16: reading-line constraint. The grid cell can be 1000+
   px wide on a 27" monitor, but a single text column at 17 px serif
   becomes unreadable past ~75 chars. Cap the head + stream at 760 px
   and centre — gives the centre body breathing gutters without
   stranding the side panes against the viewport edge. */
.docs-reader-body > .docs-reader-head,
.docs-reader-body > .docs-reader-stream {
  max-width: 760px;
  margin-inline: auto;
}
.docs-reader-empty {
  text-align: center;
  margin: 80px auto;
  max-width: 460px;
}
.docs-reader-empty .folio { display: block; margin-bottom: 12px; }
.docs-reader-loading {
  padding: 80px 0;
  text-align: center;
  color: var(--ink-3);
  font-style: italic;
}
.docs-reader-head {
  border-bottom: 1px solid var(--rule);
  padding-bottom: 14px;
  margin-bottom: 24px;
  /* v19.56.5: sticky pinning reverted — the left rail already shows the
     active document name, so duplicating it at the top of the reader
     pane is redundant. Reclaim vertical space for the actual prose. */
}
.docs-reader-head .folio { display: block; margin-bottom: 4px; }
.docs-reader-title {
  font-family: var(--display);
  font-style: italic;
  font-size: 26px;
  font-weight: 500;
  line-height: 1.2;
  margin: 0 0 8px;
  color: var(--ink);
}
.docs-reader-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  font-size: 11px;
  color: var(--ink-3);
}
.docs-reader-source { color: var(--garnet); text-decoration: none; }
.docs-reader-source:hover { text-decoration: underline; }

/* v19.47: multilingual "Read in:" strip — only rendered when CCPR Centre
   supplied 2+ language URLs for the case. Chips link to direct PDF/DOCX
   URLs on ccprcentre.org for each language; English usually mirrors the
   doc's main `link` but the others are unique. */
.docs-reader-langs {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  margin-top: 12px;
  font-family: var(--display);
  max-width: 720px;
}
.docs-reader-langs > .folio {
  font-size: 10px;
  color: var(--ink-3);
  margin-right: 2px;
}
.lang-chip {
  display: inline-flex;
  align-items: center;
  height: 22px;
  padding: 0 8px;
  font-family: var(--mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--ink-2);
  background: var(--paper-2);
  border: 1px solid var(--rule);
  border-radius: 2px;
  text-decoration: none;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.lang-chip:hover {
  background: var(--paper-3);
  border-color: var(--garnet);
  color: var(--garnet);
}
.lang-chip-en { /* slight emphasis on EN since it's our primary corpus language */
  border-color: var(--ink-3);
  color: var(--ink);
}

/* v19.46: <details> disclosure under the doc-reader title that exposes the
   full applicant list when the visible title was shortened to "First et al.".
   Closed by default — keeps the head compact for joint-communication cases
   that have 20+ applicants. */
.docs-reader-applicants {
  margin-top: 12px;
  max-width: 720px;
  font-family: var(--display);
}
.docs-reader-applicants > summary {
  list-style: none;
  cursor: pointer;
  padding: 4px 0;
  color: var(--ink-3);
  font-size: 11px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.docs-reader-applicants > summary::-webkit-details-marker { display: none; }
.docs-reader-applicants > summary::before {
  content: '▸';
  font-family: var(--mono);
  color: var(--garnet);
  transition: transform .15s;
  display: inline-block;
}
.docs-reader-applicants[open] > summary::before { transform: rotate(90deg); }
.docs-reader-applicants > summary:hover { color: var(--ink); }
.docs-reader-applicants-body {
  margin: 6px 0 0;
  padding: 8px 12px;
  font-size: 13px;
  line-height: 1.55;
  color: var(--ink-2);
  background: var(--paper-2);
  border-left: 2px solid var(--rule);
}

/* v19.45: OCR-provenance banner inside the document-reader head. Sits
   directly under the meta line, full-width, paper-2 background with a
   garnet left rule. Combines a clear "this is OCR'd text" advisory with
   a one-click "report an issue" link to the GitHub tracker. */
.docs-reader-ocr-banner {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin-top: 16px;
  padding: 12px 14px;
  background: var(--paper-2);
  border-left: 3px solid var(--garnet);
  border-radius: 2px;
  max-width: 720px;
}
.ocr-banner-tag {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  height: 22px;
  padding: 0 7px;
  background: var(--garnet);
  color: var(--paper);
  font-family: var(--mono);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  border-radius: 2px;
}
.ocr-banner-body {
  font-family: var(--display);
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--ink-2);
}
.ocr-banner-body strong { color: var(--ink); font-weight: 600; }
.ocr-banner-body a {
  color: var(--garnet);
  text-decoration: none;
  border-bottom: 1px dotted var(--garnet);
}
.ocr-banner-body a:hover { border-bottom-style: solid; }
.ocr-banner-report {
  display: inline-block;
  margin-left: 6px;
  font-weight: 600;
  white-space: nowrap;
}
/* v19.56.2: raw-OCR variant — stronger amber tone to signal "no cleanup,
   verify before citing". Distinguishes the 12 raw-OCR 1990s CAT cases
   from the 170 CCPR cases that went through the v19.47 cleanup pipeline. */
.docs-reader-ocr-banner.ocr-banner-raw {
  border-left-color: #c8741a;
  background: #fff5e6;
}
.docs-reader-ocr-banner.ocr-banner-raw .ocr-banner-tag {
  background: #c8741a;
}
.docs-reader-ocr-banner.ocr-banner-raw .ocr-banner-body a {
  color: #a85a0a;
  border-bottom-color: #a85a0a;
}

/* v19.45: small "OCR" pill on result-list rows. Renders next to the
   source badge so users can see at a glance which results came from
   OCR'd source text. Tooltip carries the cleanup-pipeline summary. */
.ocr-pill {
  display: inline-flex;
  align-items: center;
  height: 18px;
  padding: 0 6px;
  margin-right: 4px;
  background: var(--paper-3);
  color: var(--garnet);
  font-family: var(--mono);
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  border: 1px solid var(--garnet);
  border-radius: 2px;
  cursor: help;
}

.docs-reader-stream {
  max-width: 720px;
}
/* v19.43: depth-based section hierarchy in the document reader.
   Each <h3.docs-reader-section> carries a depth-N class. Only the
   levels that CHANGED since the previous paragraph are emitted; the
   right-pane outline keeps the full hierarchy + scroll-spy
   highlighting so users always know where they are. */
.docs-reader-section {
  font-family: var(--mono);
  letter-spacing: 0.08em;
  color: var(--garnet);
}
/* Top-level (Roman): full editorial mast, separator rule, ALL CAPS */
.docs-reader-section.depth-0 {
  font-size: 11px;
  text-transform: uppercase;
  margin: 36px 0 12px;
  padding-top: 14px;
  border-top: 1px solid var(--rule-soft);
}
/* Sub-level (Letter): smaller, no rule, slight indent */
.docs-reader-section.depth-1 {
  font-size: 11px;
  text-transform: none;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--ink-2, #333);
  margin: 22px 0 8px 16px;
  padding-top: 0;
  border-top: 0;
}
/* Sub-sub-level (Arabic): smallest, italic, more indent */
.docs-reader-section.depth-2 {
  font-size: 10px;
  text-transform: none;
  font-style: italic;
  letter-spacing: 0.02em;
  color: var(--ink-3, #555);
  margin: 14px 0 6px 32px;
  padding-top: 0;
  border-top: 0;
}
/* Deepest level (rarely used): even more dim */
.docs-reader-section.depth-3 {
  font-size: 9.5px;
  font-style: italic;
  letter-spacing: 0.02em;
  color: var(--ink-4, #777);
  margin: 10px 0 4px 48px;
  padding-top: 0;
  border-top: 0;
}
/* Fallback for legacy section headers without depth class */
.docs-reader-section:not([class*="depth-"]) {
  font-size: 11px;
  text-transform: uppercase;
  margin: 36px 0 12px;
  padding-top: 14px;
  border-top: 1px solid var(--rule-soft);
}
.docs-reader-para {
  display: grid;
  grid-template-columns: 64px 1fr;
  gap: 18px;
  padding: 10px 8px 10px 0;
  border-radius: 3px;
  cursor: pointer;
  transition: background .12s;
}
/* Trailing subsection label — e.g. "(a) Obligations to respect" at the end
   of a paragraph. Promote it to its own line so it reads as a subheader. */
.docs-reader-subhead {
  display: block;
  margin-top: 0.65rem;
  font-weight: 600;
  font-style: italic;
  color: var(--garnet, #6d1422);
}
.docs-reader-para:hover { background: var(--paper-2); }
.docs-reader-para.is-active {
  background: var(--paper-2);
  border-left: 2px solid var(--garnet);
  padding-left: 14px;
  margin-left: -16px;
}
/* v19.51.7 (Tier B.2): make workspace marks visible at-a-glance in
   the document reader. Bookmarked paragraphs get a thin gold rule
   on the LEFT (3 px wide, mirrors the .is-active garnet rule but
   uses the bookmark colour). Pinned + noted paragraphs get rules
   in their own colours. The colours are visible enough to scan a
   long doc and find your marks, subtle enough not to fight the
   text. .is-active wins layout precedence — the garnet rule
   replaces the gold one when the user is currently on that ¶. */
.docs-reader-para.is-bookmarked:not(.is-active) {
  border-left: 3px solid #c9a227;     /* warm gold */
  padding-left: 13px;
  margin-left: -16px;
}
.docs-reader-para.is-pinned:not(.is-active):not(.is-bookmarked) {
  border-left: 3px solid var(--jur-tone);
  padding-left: 13px;
  margin-left: -16px;
}
.docs-reader-para.has-note:not(.is-active):not(.is-bookmarked):not(.is-pinned) {
  border-left: 3px solid var(--ink-3);
  padding-left: 13px;
  margin-left: -16px;
}
/* When BOTH marks apply, layer them: gold rule + a subtle right-edge
   wedge for the second mark. */
.docs-reader-para.is-bookmarked.has-note::after,
.docs-reader-para.is-bookmarked.is-pinned::after {
  content: '';
  position: absolute;
  top: 8px; bottom: 8px; right: 4px;
  width: 2px;
  background: var(--ink-3);
  border-radius: 1px;
}
.docs-reader-para.is-bookmarked.is-pinned::after { background: var(--jur-tone); }
.docs-reader-para { position: relative; }
.docs-reader-para-marker {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  color: var(--ink-3);
  font-size: 10px;
}
.docs-reader-para-marker .mono { color: var(--ink-4); font-size: 11px; }
/* v19.43: preamble-entry badge — replaces "¶0" on isPreamble paragraphs */
.docs-reader-para-marker .docs-preamble-badge {
  display: inline-block;
  padding: 1px 6px;
  font-family: var(--mono-stack, ui-monospace, "SF Mono", Menlo, monospace);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--garnet, #8b1a1a);
  background: var(--garnet-bg, rgba(139, 26, 26, 0.08));
  border: 1px solid var(--garnet-border, rgba(139, 26, 26, 0.25));
  border-radius: 3px;
  white-space: nowrap;
}
/* v19.43: Cite + Copy actions — progressive-disclosure pattern.
   At rest, only the ¶N marker and ☆ bookmark are visible. The cite +
   copy actions reveal on hover, keyboard focus (:focus-within from any
   descendant), or when the paragraph is the active one (set by click /
   touch / URL deep-link).  Mirrors Notion/Linear/GitHub paragraph-
   handle UX: clean reading mode, contextual actions on demand. */
.docs-reader-para-marker .docs-para-act {
  display: block;
  width: 100%;
  text-align: left;
  background: transparent;
  border: 0;
  padding: 1px 0;
  margin: 0;
  font-family: var(--mono-stack, ui-monospace, "SF Mono", Menlo, monospace);
  font-size: 10px;
  letter-spacing: 0.04em;
  color: var(--ink-3, #555);
  cursor: pointer;
  opacity: 0;
  pointer-events: none;
  transition: opacity 150ms ease, color 120ms ease;
}
/* Reveal triggers — hover, keyboard focus inside the para, or active state */
.docs-reader-para:hover .docs-para-act,
.docs-reader-para:focus-within .docs-para-act,
.docs-reader-para.is-active .docs-para-act {
  opacity: 1;
  pointer-events: auto;
}
.docs-reader-para-marker .docs-para-act .mono {
  border-bottom: 1px dotted transparent;
  padding-bottom: 1px;
}
.docs-reader-para-marker .docs-para-act:hover {
  color: var(--garnet);
}
.docs-reader-para-marker .docs-para-act:hover .mono {
  border-bottom-color: var(--garnet);
}
.docs-reader-para-marker .docs-para-act-cite { color: var(--garnet); }
.docs-reader-para-marker .docs-para-act-cite .mono { font-weight: 600; }
.docs-reader-para-marker .docs-para-act.is-flash {
  color: var(--paper) !important;
  background: var(--garnet);
  padding: 1px 4px;
  border-radius: 2px;
  opacity: 1;        /* keep visible during the flash even on mouse-out */
}
.docs-reader-para-marker .docs-para-act.is-flash .mono { border-bottom-color: transparent; }
/* Slim vertical spacing between marker number, bookmark, and acts */
.docs-reader-para-marker .docs-para-act-cite { margin-top: 6px; }
.docs-reader-para-marker .docs-para-act-copy { margin-top: 1px; }
/* Touch-device polish: ensure actions are reachable when the paragraph
   is active, since :hover doesn't really exist on touch. */
@media (hover: none) {
  .docs-reader-para .docs-para-act { transition: opacity 0ms; }
}

/* v19.43: footnote popover now shows resolvedText for Ibid./See-note./
   See-para. references. The literal text appears at the top, then a
   small label, then the resolved citation in italics. */
.fn-popover-literal {
  font-style: italic;
  color: var(--ink-3, #555);
  margin-bottom: 6px;
}
.fn-popover-resolved-label {
  display: block;
  font-size: 9px;
  letter-spacing: 0.08em;
  margin-top: 8px;
  margin-bottom: 3px;
  color: var(--garnet);
}
.fn-popover-resolved {
  color: var(--ink);
}
.docs-reader-para-marker .docs-para-bm,
.docs-reader-para-marker .docs-para-pin,
.docs-reader-para-marker .docs-para-cite {
  background: transparent;
  border: 0;
  cursor: pointer;
  padding: 1px 4px;
  font-size: 13px;
  color: var(--ink-4);
  border-radius: 2px;
  font-family: inherit;
}
.docs-reader-para-marker .docs-para-bm.on { color: var(--garnet); }
.docs-reader-para-marker .docs-para-pin.on { color: var(--garnet); }
.docs-reader-para-marker .docs-para-cite {
  font-family: var(--display);
  font-size: 16px;
  color: var(--garnet);
  line-height: 1;
}
.docs-reader-para-marker .docs-para-bm:hover,
.docs-reader-para-marker .docs-para-pin:hover,
.docs-reader-para-marker .docs-para-cite:hover { background: var(--paper-3); color: var(--ink); }
.docs-reader-para-marker .docs-para-cite:hover { background: var(--garnet); color: var(--paper); }
.docs-reader-para-text {
  font-family: var(--display);
  font-size: calc(15px * var(--dossier-font, 1));
  line-height: 1.7;
  color: var(--ink);
  margin: 0;
}

/* DRAWER ───────────────────────────────────────────────────────
   v19.43-fix3: not sticky — bounded by docs-reader grid cell. */
.docs-drawer {
  overflow-y: auto;
  padding: 0;
  min-height: 0;
}
.docs-drawer-collapse {
  position: absolute;
  top: 8px;
  left: 6px;
  z-index: 3;
  background: transparent;
  border: 0;
  cursor: pointer;
  font-family: var(--mono);
  font-size: 14px;
  color: var(--ink-3);
  width: 22px;
  height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 2px;
}
.docs-drawer-collapse:hover { background: var(--paper-3); color: var(--ink); }
.docs-drawer.is-collapsed .docs-drawer-body { display: none; }
.docs-drawer.is-collapsed .docs-drawer-collapse::before { content: '«'; }
.docs-drawer-body { padding: 36px 16px 80px; }
.docs-drawer-block { margin-bottom: 28px; }
.docs-drawer-block h3.folio { display: block; margin: 0 0 8px; font-size: 11px; }

.docs-outline-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.docs-outline-link {
  display: grid;
  grid-template-columns: 56px 1fr;
  gap: 8px;
  align-items: baseline;
  padding: 5px 8px;
  border-left: 2px solid transparent;
  font-size: 12px;
  line-height: 1.35;
  color: var(--ink-2);
  text-decoration: none;
  border-radius: 2px;
}
.docs-outline-link:hover {
  background: var(--paper-3);
  color: var(--ink);
  border-left-color: var(--garnet);
}
/* v19.43: scroll-spy highlight — the outline entry that the topmost
   visible paragraph belongs to gets a garnet bar + paper-3 wash, so
   the user always knows their location in the hierarchy without the
   middle pane having to repeat the full path on every section break. */
.docs-outline-link.is-active {
  background: var(--paper-3);
  color: var(--ink);
  border-left-color: var(--garnet);
  border-left-width: 3px;
}
.docs-outline-link.is-active .docs-outline-leaf {
  color: var(--garnet);
  font-weight: 600;
}
.docs-outline-link.is-active .docs-outline-ancestors {
  color: var(--ink-3, #555);
}
.docs-outline-link .mono { color: var(--ink-4); font-size: 10px; }
/* v19.43: each unique section appears ONCE in the outline, with its
   paragraph range, the leaf heading prominent and any ancestor chain
   shown faintly underneath.  Indent by depth so nested sub-sections
   read as a tree. */
.docs-outline-item.depth-1 { padding-left: 8px; }
.docs-outline-item.depth-2 { padding-left: 16px; }
.docs-outline-item.depth-3 { padding-left: 24px; }
.docs-outline-leaf {
  display: block;
  font-weight: 500;
  color: var(--ink);
}
.docs-outline-ancestors {
  display: block;
  font-size: 10px;
  font-style: italic;
  margin-top: 1px;
  color: var(--ink-4);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.docs-drawer-active {
  font-size: 11px;
  color: var(--garnet);
  margin-bottom: 8px;
  word-break: break-all;
}
.docs-drawer-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 10px;
}
.docs-drawer-actions .btn { font-size: 11px; padding: 4px 8px; }
.docs-drawer-note {
  display: block;
  width: 100%;
  padding: 8px 10px;
  font-family: var(--body);
  font-size: 12px;
  line-height: 1.5;
  color: var(--ink-2);
  background: var(--paper);
  border: 1px dashed var(--rule);
  border-radius: 2px;
  resize: vertical;
  box-sizing: border-box;
  margin-bottom: 8px;
}
.docs-drawer-note:focus { outline: none; border: 1px solid var(--garnet); color: var(--ink); }
.docs-drawer-cite { margin-top: 8px; }
.docs-drawer-cite > summary { list-style: none; cursor: pointer; }
.docs-drawer-cite > summary::-webkit-details-marker { display: none; }
.docs-drawer-cite-pop {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 6px;
  padding: 8px;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 2px;
}
.docs-drawer-cite-pop .cite-opt {
  display: grid;
  grid-template-columns: 64px 1fr;
  gap: 8px;
  padding: 4px 8px;
  background: transparent;
  border: 0;
  cursor: pointer;
  font-size: 11px;
  text-align: left;
  color: var(--ink-2);
  border-radius: 2px;
}
.docs-drawer-cite-pop .cite-opt:hover { background: var(--paper-3); color: var(--ink); }
.docs-drawer-cite-pop .cite-fmt { font-family: var(--mono); color: var(--garnet); font-size: 10px; }

/* The old single-column body is replaced by the rail+reader layout above.
   The mast keeps its style; no rule changes needed there. */
.docs-mast { padding: 0; }
.docs-mast-inner { max-width: 1600px; padding: 22px 40px 16px; }
.docs-tools { display: none; }   /* tools moved into the rail */

/* ─────────────  ABOUT VIEW  ───────────── */
.about {
  max-width: 1100px;
  margin: 0 auto;
  padding: 36px 40px 100px;
}
.about-inner > .folio { display: block; margin-bottom: 6px; }
.about-title {
  font-size: 36px;
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: 1.15;
  margin: 4px 0 28px;
  max-width: 720px;
}
/* ============================================================
   Workspace layer (Tier B — bookmarks · notes · pins · saves)
   ============================================================ */

/* Result-card workspace marks (small column on the right of each result) */
.result-marks {
  display: flex;
  gap: 4px;
  margin-top: 8px;
  flex-wrap: wrap;
}
.ws-mark {
  font-family: var(--display);
  font-size: 14px;
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 50%;
  width: 26px;
  height: 26px;
  cursor: pointer;
  padding: 0;
  color: var(--ink-3);
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.ws-mark:hover { background: var(--paper-2); color: var(--ink); }
.ws-mark.on { background: var(--garnet); border-color: var(--garnet); color: var(--paper); }
.ws-mark.ws-mark-note { cursor: default; }

/* v18 unified toolbar ─────────────────────────────────────────── */
.dossier-toolbar {
  display: grid;
  /* v19.5: equal-width grid. The v18.2 attempt to highlight Cite by
     giving it a wider cell + a special border + bold garnet text made
     it visually loud and inconsistent with the rest of the toolbar.
     Equal cells let the row breathe; Cite still gets a distinct
     hover/open treatment in CSS below.
     v19.14: bumped 6→7 (Flag).
     v19.15: still 7 (Pin out, Link in). */
  grid-template-columns: repeat(7, 1fr);
  gap: 4px;
  margin-top: 20px;
  padding: 8px;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: var(--paper);
}
.dossier-tool {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  min-height: 50px;
  padding: 6px 4px;
  background: transparent;
  border: 0;
  border-radius: 3px;
  cursor: pointer;
  font-family: var(--mono);
  color: var(--ink-2);
  transition: background 0.12s, color 0.12s;
}
.dossier-tool:hover {
  background: var(--paper-3);
  color: var(--ink);
}
.dossier-tool.on {
  background: var(--garnet);
  color: var(--paper);
}
.dossier-tool.is-flash {
  background: oklch(70% 0.18 145);   /* green-ish OK indication */
  color: var(--paper);
}
/* v19.16: same flash treatment for the one-click cite buttons in the
   middle panels (result rows + docs-reader paragraph rows). The user
   needs explicit feedback that "I just copied something" because there
   is no popover modal to confirm it. */
.ws-mark-cite.is-flash,
.docs-para-cite.is-flash {
  background: oklch(70% 0.18 145);
  color: var(--paper);
}
.dossier-tool-icon {
  font-size: 16px;
  line-height: 1;
  font-family: var(--display);
}
.dossier-tool-label {
  font-size: 10px;
  letter-spacing: 0.04em;
  line-height: 1;
  text-transform: uppercase;
}
.dossier-tool-summary {
  background: transparent;
  border: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  width: 100%;
  height: 100%;
  cursor: pointer;
  font-family: var(--mono);
  color: inherit;
  padding: 0;
}
/* v19.5: Cite cell. Same shape as every other dossier-tool — the
   only thing that differentiates it is the open-state inversion below
   (which mirrors how the bookmark "on" state works), so the user
   sees a clear "this menu is open" affordance without yet another
   colour scheme on the toolbar. */
.dossier-tool-cite { padding: 0; }
.dossier-tool-cite.is-open .dossier-tool-summary {
  background: var(--ink);
  color: var(--paper);
  border-radius: 3px;
}
.dossier-tool-cite.is-open .dossier-tool-icon,
.dossier-tool-cite.is-open .dossier-tool-label { color: var(--paper); }

/* v18.2: shared inline cite popover — anchored to whatever button
   triggered it (a result-row mark or a docs-reader paragraph). */
.inline-cite-pop {
  position: absolute;
  z-index: 80;
  min-width: 220px;
  background: var(--paper);
  border: 1px solid var(--ink);
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.16);
  display: flex;
  flex-direction: column;
}
.inline-cite-pop .cite-opt {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 9px 14px;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--rule-soft, var(--rule));
  text-align: left;
  cursor: pointer;
  font-family: var(--body);
  color: var(--ink);
}
.inline-cite-pop .cite-opt:last-child { border-bottom: 0; }
.inline-cite-pop .cite-opt:hover { background: var(--paper-2); }
.inline-cite-pop .cite-fmt {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  color: var(--garnet);
  font-weight: 600;
  min-width: 56px;
}
.inline-cite-pop .cite-name { font-size: 13px; }

/* New per-row Cite button (lives inside .result-marks). Uses the same
   glyph as the dossier toolbar so it reads consistently. */
.ws-mark-cite {
  font-size: 16px;
  font-family: var(--display);
  color: var(--garnet);
}
.ws-mark-cite:hover { background: var(--garnet); color: var(--paper); }

/* Citation popover — anchored to the cite button, doesn't push layout.
   v19.16: opens UPWARD (`bottom` instead of `top`) so the 9-format list
   doesn't get clipped by the viewport bottom — the toolbar sits near
   the dossier's bottom edge, with the blockquote giving plenty of
   headroom above. Drop shadow flipped to point downward. */
.cite-pop {
  position: absolute;
  right: 0;
  bottom: calc(100% + 6px);
  z-index: 30;
  min-width: 240px;
  background: var(--paper);
  border: 1px solid var(--ink);
  box-shadow: 0 -10px 28px rgba(0, 0, 0, 0.14);
  display: flex;
  flex-direction: column;
}
.cite-pop[hidden] { display: none; }
/* Star-marker on the user's currently preferred format. Tiny, monochrome
   so it doesn't compete with the format label. */
.cite-opt.is-default .cite-fmt::after {
  content: ' ★';
  color: var(--garnet);
  font-size: 9px;
  letter-spacing: 0;
}

/* Note editor — opens in a row below the toolbar, full width. */
.dossier-note-wrap {
  margin-top: 8px;
}
.dossier-note-wrap[hidden] { display: none; }
.dossier-note {
  display: block;
  width: 100%;
  min-height: 84px;
  padding: 10px 12px;
  font-family: var(--body);
  font-size: 13px;
  line-height: 1.55;
  background: var(--paper-2);
  border: 1px solid var(--rule);
  border-radius: 3px;
  resize: vertical;
  color: var(--ink);
  box-sizing: border-box;
}
.dossier-note:focus {
  outline: none;
  border-color: var(--garnet);
}

/* "Open original document" — promoted to a separate full-width link
   so it doesn't compete with the in-app actions for visual weight. */
.dossier-original {
  margin-top: 12px;
  text-align: right;
}
.dossier-original-link {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-3);
  text-decoration: none;
  letter-spacing: 0.04em;
}
.dossier-original-link:hover {
  color: var(--garnet);
  text-decoration: underline;
}

/* Reading-mode "Exit" pill in reading mode — unchanged but now the
   toolbar has identical sizing so the floating button below the bar
   doesn't visually mismatch. */
.reading-mode-btn { font-size: inherit; padding: 6px 4px; }
.reading-mode-btn.is-active { background: var(--garnet); color: var(--paper); }

/* Year histogram (B4) */
.year-histogram {
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px dotted var(--rule);
}
.yh-svg {
  width: 100%;
  height: 36px;
  display: block;
}
.yh-bar { cursor: pointer; transition: opacity 0.12s; }
.yh-bar.in-range  { fill: var(--garnet); opacity: 0.85; }
.yh-bar.out-range { fill: var(--rule);   opacity: 0.55; }
/* v19.43-fix16: bars with 0 hits in current query/filter — visible
   but very dim, so the histogram still shows the corpus shape but
   user can see at-a-glance which years have NO results for the
   current query. */
.yh-bar.is-zero { fill: var(--rule); opacity: 0.18; }
.yh-bar:hover     { opacity: 1; }
.yh-axis {
  display: flex;
  justify-content: space-between;
  font-family: var(--mono);
  font-size: 9px;
  color: var(--ink-4);
  margin-top: 2px;
}

/* Workspace nav-link badge */
.workspace-badge {
  display: inline-block;
  margin-left: 4px;
  background: var(--garnet);
  color: var(--paper);
  font-family: var(--mono);
  font-size: 10px;
  padding: 1px 5px;
  border-radius: 8px;
  vertical-align: middle;
}

/* Workspace view */
.workspace-shell { padding: 28px 40px 80px; max-width: 980px; margin: 0 auto; }
.workspace-head { margin-bottom: 28px; padding-bottom: 18px; border-bottom: 1px solid var(--rule); }
.workspace-head .folio { display: block; margin-bottom: 6px; }
.workspace-title { font-size: 30px; line-height: 1.15; margin: 0 0 8px; color: var(--ink); }
.workspace-sub   { color: var(--ink-3); font-size: 14px; line-height: 1.55; margin: 0; max-width: 720px; }
.workspace-grid  { display: grid; grid-template-columns: 1fr; gap: 28px; }
.ws-block        { padding: 18px 20px; border: 1px solid var(--rule); border-radius: 3px; background: var(--paper); }
.ws-block h3     { margin: 0 0 12px; font-size: 11px; color: var(--ink); }
.ws-block .dim   { color: var(--ink-4); font-weight: normal; margin-left: 4px; }
.ws-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 12px; }
.ws-row {
  position: relative;
  padding: 12px 14px 12px 14px;
  background: var(--paper-2);
  border-left: 2px solid var(--garnet);
  border-radius: 3px;
}
.ws-row-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: baseline;
  font-size: 12px;
  margin-bottom: 6px;
}
.ws-row-meta .dim { color: var(--ink-3); }
.ws-row-snippet  { font-size: 13px; color: var(--ink); margin: 0 0 6px; line-height: 1.55; }
.ws-note         { font-size: 12px; color: var(--ink-2); background: var(--paper); padding: 8px 10px; border-radius: 2px; border: 1px dashed var(--rule); margin: 0; }
.ws-jump         { color: var(--garnet); text-decoration: none; font-size: 11px; }
.ws-jump:hover   { text-decoration: underline; }
.ws-row-del {
  position: absolute;
  top: 8px;
  right: 8px;
  background: transparent;
  border: 0;
  color: var(--ink-3);
  cursor: pointer;
  font-size: 18px;
  line-height: 1;
}
.ws-row-del:hover { color: var(--garnet); }
.ws-searches .ws-row { padding-right: 36px; display: flex; gap: 14px; align-items: baseline; flex-wrap: wrap; }
.ws-search-link { color: var(--ink); font-family: var(--display); font-size: 14px; text-decoration: none; }
.ws-search-link:hover { color: var(--garnet); text-decoration: underline; }

/* v15: workspace UX — top export bar, expandable snippet fold, inline note editor. */
.ws-export-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  margin-bottom: 18px;
  border: 1px dashed var(--rule);
  border-radius: 3px;
  background: var(--paper);
  flex-wrap: wrap;
}
.ws-export-actions { display: inline-flex; gap: 6px; }

/* Snippet collapse toggle — uses native <details> so keyboard / screen-reader
   support comes free. The marker is hidden, replaced by the "Collapse"
   summary text. */
.ws-snippet-fold > summary { list-style: none; cursor: pointer; }
.ws-snippet-fold > summary::-webkit-details-marker { display: none; }
.ws-snippet-fold[open] > summary::after  { content: ' ▴'; }
.ws-snippet-fold:not([open]) > summary::after { content: ' ▾'; }
.ws-snippet-toggle { font-size: 11px; user-select: none; }
.ws-snippet-fold:not([open]) > .ws-row-snippet { display: none; }

/* Inline note editor on every workspace row.  Empty by default — but
   shows a soft border so users discover it. Auto-grows isn't worth the
   JS complexity here; rows=2 fits the common case. */
.ws-row-note {
  display: block;
  width: 100%;
  margin-top: 8px;
  padding: 7px 10px;
  font-family: var(--body);
  font-size: 12px;
  line-height: 1.5;
  color: var(--ink-2);
  background: var(--paper);
  border: 1px dashed var(--rule);
  border-radius: 2px;
  resize: vertical;
  box-sizing: border-box;
  min-height: 38px;
}
.ws-row-note:focus {
  outline: none;
  border-color: var(--garnet);
  border-style: solid;
  color: var(--ink);
}
.ws-row-note::placeholder { color: var(--ink-4); font-style: italic; }

/* Diff tray (B3) — bottom-right floating widget.
   `[hidden]` MUST win over the visible-state rules below — without the
   explicit override the class selectors had higher specificity than the
   browser default `[hidden] { display: none }`, leaving the empty tray
   and modal on the page and stealing clicks across the whole viewport. */
.diff-tray[hidden],
.diff-modal[hidden] { display: none !important; }
.diff-tray {
  position: fixed;
  bottom: 16px;
  right: 16px;
  z-index: 80;
  width: 280px;
  background: var(--paper);
  border: 1px solid var(--ink);
  box-shadow: 0 12px 32px rgba(0,0,0,.16);
  font-family: var(--display);
}
.diff-tray-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 12px;
  background: var(--ink);
  color: var(--paper);
}
.diff-tray-head .folio { color: var(--paper); }
.diff-clear {
  background: transparent;
  border: 0;
  color: var(--paper);
  font-size: 18px;
  cursor: pointer;
  line-height: 1;
}
.diff-tray-list { list-style: none; padding: 8px 12px; margin: 0; display: flex; flex-direction: column; gap: 6px; }
.diff-tray-item {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
}
.diff-tray-num {
  background: var(--garnet);
  color: var(--paper);
  font-family: var(--mono);
  font-size: 10px;
  padding: 1px 5px;
  border-radius: 2px;
}
.diff-tray-sig { font-family: var(--mono); font-size: 11px; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.diff-tray-pn  { font-family: var(--mono); font-size: 10px; color: var(--ink-3); }
.diff-tray-pop {
  background: transparent;
  border: 0;
  color: var(--ink-3);
  cursor: pointer;
  font-size: 14px;
  padding: 0 4px;
  line-height: 1;
}
.diff-tray-pop:hover { color: var(--garnet); }
.diff-tray-foot { padding: 10px 12px; border-top: 1px solid var(--rule); display: flex; justify-content: center; }
.diff-tray-foot .dim { color: var(--ink-4); font-size: 10px; }

/* Diff modal */
.diff-modal {
  position: fixed;
  inset: 0;
  z-index: 220;
  display: flex;
  align-items: stretch;
  justify-content: center;
  padding: 4vh 4vw;
}
.diff-modal-backdrop { position: absolute; inset: 0; background: rgba(20, 18, 16, 0.65); }
.diff-modal-card {
  position: relative;
  background: var(--paper);
  border: 1px solid var(--ink);
  width: 100%;
  max-width: 1280px;
  display: flex;
  flex-direction: column;
  box-shadow: 0 24px 60px rgba(0,0,0,.30);
}
.diff-modal-head { display: flex; justify-content: space-between; padding: 14px 20px; border-bottom: 1px solid var(--rule); }
.diff-modal-close { background: transparent; border: 0; font-size: 24px; line-height: 1; cursor: pointer; color: var(--ink-3); }
.diff-modal-close:hover { color: var(--garnet); }
.diff-modal-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--rule); flex: 1; overflow: auto; }
.diff-pane { padding: 22px 26px; background: var(--paper); overflow-y: auto; }
.diff-pane-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.diff-pane-title { font-family: var(--serif); font-size: 18px; line-height: 1.3; margin: 4px 0; color: var(--ink); }
.diff-pane-meta { display: flex; gap: 10px; flex-wrap: wrap; font-size: 12px; color: var(--ink-3); margin-bottom: 14px; }
.diff-pane-country { color: var(--garnet); font-style: italic; }
.diff-pane-pn { color: var(--ink); font-family: var(--mono); }
.diff-pane-text { font-family: var(--display); font-size: 15px; line-height: 1.7; color: var(--ink); margin: 0; }
.diff-modal-foot { padding: 8px 20px; border-top: 1px solid var(--rule); background: var(--paper-2); text-align: center; color: var(--ink-4); font-size: 9px; letter-spacing: 0.08em; }
/* v19.3: report-a-problem modal. Pattern mirrors the diff-modal so
   the visual language stays consistent across the two dialogs. */
.report-modal[hidden] { display: none !important; }
.report-modal {
  position: fixed;
  inset: 0;
  z-index: 230;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 4vh 4vw;
}
.report-modal-backdrop { position: absolute; inset: 0; background: rgba(20, 18, 16, 0.65); }
.report-modal-card {
  position: relative;
  background: var(--paper);
  border: 1px solid var(--ink);
  width: 100%;
  max-width: 560px;
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  box-shadow: 0 24px 60px rgba(0,0,0,.30);
  overflow: hidden;
}
.report-modal-head {
  position: relative;
  padding: 18px 22px 12px;
  border-bottom: 1px solid var(--rule);
}
.report-modal-head .folio { display: block; margin-bottom: 4px; }
.report-modal-title {
  font-family: var(--display);
  font-size: 20px;
  font-style: italic;
  font-weight: 500;
  color: var(--ink);
  margin: 0;
}
.report-modal-close {
  position: absolute;
  top: 14px;
  right: 14px;
  background: transparent;
  border: 0;
  font-size: 24px;
  line-height: 1;
  cursor: pointer;
  color: var(--ink-3);
}
.report-modal-close:hover { color: var(--garnet); }
.report-form {
  padding: 16px 22px 20px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.report-kind {
  border: 1px dashed var(--rule);
  padding: 10px 12px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px 14px;
  margin: 0;
}
.report-kind legend {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--garnet);
  padding: 0 6px;
}
.report-kind label {
  display: flex;
  flex-direction: column;
  cursor: pointer;
  font-size: 13px;
  color: var(--ink);
}
.report-kind label small {
  font-size: 11px;
  color: var(--ink-3);
  font-style: italic;
  margin-left: 22px;
}
.report-kind label input { margin-right: 6px; }
.report-context {
  background: var(--paper-2);
  border: 1px solid var(--rule);
  border-radius: 2px;
  padding: 8px 12px;
  font-size: 12px;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
}
.report-context .folio { color: var(--garnet); }
.report-context .mono { color: var(--ink-2); font-size: 11px; word-break: break-all; }
.report-context-toggle {
  margin-left: auto;
  font-size: 11px;
  color: var(--ink-3);
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.report-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.report-field .folio { display: block; }
.report-field textarea,
.report-field input {
  font-family: var(--body);
  font-size: 13px;
  line-height: 1.5;
  padding: 8px 10px;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 2px;
  color: var(--ink);
  resize: vertical;
  box-sizing: border-box;
}
.report-field textarea:focus,
.report-field input:focus {
  outline: none;
  border-color: var(--garnet);
}
.report-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 6px;
}
.report-note {
  font-size: 11px;
  color: var(--ink-3);
  font-style: italic;
  line-height: 1.5;
  margin: 0;
}
.report-status {
  font-family: var(--mono);
  font-size: 12px;
  margin: 0;
  padding: 8px 10px;
  border-radius: 2px;
}
.report-status.is-pending { background: var(--paper-2); color: var(--ink-3); }
.report-status.is-ok      { background: oklch(94% 0.05 145); color: oklch(40% 0.15 145); }
.report-status.is-err     { background: oklch(94% 0.07 25);  color: var(--garnet); }

@media (max-width: 800px) {
  .diff-modal-grid { grid-template-columns: 1fr; }
  .diff-tray { width: 240px; bottom: 8px; right: 8px; }
}

/* ─── Command palette ⌘K (A2) ─── */
.cmdk-root {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  padding: 12vh 16px 0;
  font-family: var(--display);
}
.cmdk-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(20, 18, 16, 0.55);
  backdrop-filter: blur(2px);
}
.cmdk-card {
  position: relative;
  width: 100%;
  max-width: 660px;
  background: var(--paper);
  border: 1px solid var(--ink);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.30);
  display: flex;
  flex-direction: column;
  max-height: 78vh;
}
.cmdk-input-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--rule);
}
.cmdk-prompt {
  font-family: var(--mono);
  color: var(--garnet);
  font-size: 18px;
  line-height: 1;
}
.cmdk-input-row input {
  flex: 1;
  border: 0;
  background: transparent;
  font-family: var(--display);
  font-size: 16px;
  outline: none;
  color: var(--ink);
}
.cmdk-input-row input::placeholder { color: var(--ink-4); font-style: italic; }
.cmdk-esc {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  padding: 2px 6px;
  border: 1px solid var(--rule);
  color: var(--ink-3);
}
.cmdk-results {
  overflow-y: auto;
  max-height: 60vh;
}
.cmdk-item {
  display: grid;
  grid-template-columns: 90px 1fr auto;
  gap: 12px;
  padding: 10px 16px;
  font-size: 13px;
  cursor: pointer;
  border-bottom: 1px dotted var(--rule);
  align-items: center;
}
.cmdk-item:hover, .cmdk-item.focus { background: var(--paper-2); }
.cmdk-item.focus { box-shadow: inset 3px 0 0 var(--garnet); }
.cmdk-kind {
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.12em;
  color: var(--ink-3);
  text-transform: uppercase;
}
.cmdk-label {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
}
.cmdk-icon { font-size: 14px; line-height: 1; }
.cmdk-label > span:nth-child(2) {
  color: var(--ink);
  font-size: 13px;
}
.cmdk-sub {
  color: var(--ink-3);
  font-size: 11px;
  font-family: var(--mono);
}
.cmdk-enter {
  color: var(--ink-4);
  font-family: var(--mono);
}
.cmdk-empty {
  padding: 40px 20px;
  text-align: center;
  color: var(--ink-3);
  font-size: 12px;
  font-style: italic;
}
.cmdk-foot {
  padding: 8px 16px;
  border-top: 1px solid var(--rule);
  background: var(--paper-2);
  font-size: 9px;
  letter-spacing: 0.08em;
  color: var(--ink-4);
  text-align: center;
}

/* Freshness card on the About page — traffic-light "last refreshed" indicator.
   Three tones (fresh < 30d, aging 30-60d, stale > 60d) keyed off manifest.builtAt. */
.freshness-card {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  margin: 0 0 28px;
  padding: 14px 18px;
  border: 1px solid var(--rule);
  border-left-width: 4px;
  border-radius: 3px;
  background: var(--paper-2);
}
.freshness-card .folio { display: block; margin-bottom: 4px; }
.freshness-dot {
  flex-shrink: 0;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  margin-top: 4px;
}
.freshness-fresh { border-left-color: #2c6e3a; }
.freshness-fresh .freshness-dot { background: #2c6e3a; box-shadow: 0 0 0 3px rgba(44,110,58,.15); }
.freshness-aging { border-left-color: #b87f1f; }
.freshness-aging .freshness-dot { background: #b87f1f; box-shadow: 0 0 0 3px rgba(184,127,31,.15); }
.freshness-stale { border-left-color: #b22222; }
.freshness-stale .freshness-dot { background: #b22222; box-shadow: 0 0 0 3px rgba(178,34,34,.15); }
.freshness-headline {
  font-family: var(--display);
  font-size: 16px;
  color: var(--ink);
}
.freshness-headline strong { font-weight: 500; }
.freshness-date { color: var(--ink-3); font-style: italic; margin-left: 4px; }
.freshness-meta {
  font-family: var(--body);
  font-size: 13px;
  line-height: 1.55;
  color: var(--ink-2);
  margin-top: 4px;
}

.about-grid {
  display: grid;
  /* v19.56.10: bumped from 320px → 400px. With the previous floor we got
     3-4 cramped columns on a 1280-wide viewport, each ~320px (too narrow
     for the dense Jurisprudence / Methodology paragraphs to breathe).
     400px floors at 2 columns on standard laptops, 3 on ultra-wide. */
  grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
  gap: 32px 48px;
  margin-top: 16px;
}
.about-block h3.folio {
  display: block;
  color: var(--garnet);
  margin: 0 0 10px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--rule);
}
.about-block p {
  font-family: var(--display);
  font-size: 15px;
  line-height: 1.7;
  margin: 0;
  color: var(--ink);
}
.about-link {
  color: var(--garnet);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 0.5px;
}
.about-link:hover { color: var(--garnet-2); }
.about-block code.mono {
  font-size: 13px;
  background: var(--paper-3);
  padding: 0 4px;
  border: 1px solid var(--rule);
}

/* v19.43: methodology block — full-width grid cell so the intro
   paragraph + accordion sub-topics get a comfortable reading column. */
.about-block-methodology { grid-column: 1 / -1; }
.about-block-methodology p { max-width: 78ch; }

/* In-page TOC strip — chip-style links to each accordion section.
   Sits between the always-visible intro and the collapsible details. */
.about-method-toc {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px 14px;
  margin: 16px 0 12px;
  padding: 10px 12px;
  background: var(--paper-3);
  border-left: 3px solid var(--garnet);
  border-radius: 2px;
  font-family: var(--display);
  font-size: 13px;
}
.about-method-toc .folio.dim {
  font-size: 10px;
  letter-spacing: 0.06em;
}
.about-method-toc-link {
  color: var(--ink);
  border-bottom: 1px dotted var(--ink-4);
  text-decoration: none;
  padding-bottom: 1px;
  transition: color 100ms, border-color 100ms;
}
.about-method-toc-link:hover {
  color: var(--garnet);
  border-bottom-color: var(--garnet);
}

/* Accordion details */
.about-method-detail {
  border-top: 1px solid var(--rule);
  padding: 10px 0;
}
.about-method-detail:first-of-type { border-top: 1px solid var(--rule); }
.about-method-detail[open] {
  background: linear-gradient(to bottom,
              rgba(139, 26, 26, 0.025), rgba(139, 26, 26, 0));
}
.about-method-summary {
  list-style: none;
  display: flex;
  align-items: baseline;
  gap: 12px;
  flex-wrap: wrap;
  cursor: pointer;
  padding: 4px 0;
  outline: none;
  user-select: none;
}
.about-method-summary::-webkit-details-marker { display: none; }
.about-method-summary::before {
  content: "›";
  display: inline-block;
  font-family: var(--mono-stack, ui-monospace, "SF Mono", Menlo, monospace);
  color: var(--garnet);
  font-size: 16px;
  width: 14px;
  text-align: center;
  transition: transform 150ms ease;
  transform-origin: center;
}
.about-method-detail[open] .about-method-summary::before {
  transform: rotate(90deg);
}
.about-method-summary-title {
  font-family: var(--display);
  font-weight: 600;
  font-size: 15px;
  color: var(--ink);
  letter-spacing: 0.005em;
}
.about-method-summary-hint {
  font-family: var(--display);
  font-style: italic;
  font-size: 13px;
  color: var(--ink-3);
}
.about-method-summary:hover .about-method-summary-title { color: var(--garnet); }
.about-method-summary:focus-visible {
  outline: 2px solid var(--garnet);
  outline-offset: 3px;
  border-radius: 2px;
}
.about-method-body {
  padding: 4px 0 8px 26px;       /* indent under the chevron */
}
.about-method-body p { margin-top: 0; }
.about-method-body > p + p { margin-top: 0.7em; }

/* v19.56.12: deliberate semantic columns. Earlier we tried
   `column-count: 2` for magazine-style flow but it snaked the prose
   awkwardly — the reader couldn't tell whether to read down the left
   column first or jump to the right paragraph that started a new
   topic, and the full-width bullet lists fractured the reading
   order into 4 disconnected zones. Now: each accordion body uses
   either a single readable column (≤78ch, centred) or an explicit
   .method-grid for content that's naturally paired
   (Pipeline ↔ Quality gates; Known limitations ↔ Grounding). The
   grid is two equal-weight cells; on narrow viewports it collapses
   to one column so mobile reading order stays predictable. */
.about-method-body > p,
.about-method-body > ul,
.about-method-body > ol {
  max-width: 78ch;
}
.about-method-body .method-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px 40px;
  margin: 0.8em 0;
}
.about-method-body .method-grid > * {
  margin: 0;
  max-width: none;
}
.about-method-body .method-grid h4 {
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.95em;
  color: var(--garnet);
  margin: 0 0 0.4em;
  letter-spacing: 0.02em;
}
.about-method-body .method-grid ul,
.about-method-body .method-grid ol {
  margin: 0.4em 0 0;
  padding-left: 1.2em;
}
.about-method-body .method-grid li + li { margin-top: 0.35em; }
.about-method-body .method-metrics {
  list-style: none;
  padding-left: 0;
}
.about-method-body .method-metrics li {
  position: relative;
  padding-left: 1.1em;
}
.about-method-body .method-metrics li::before {
  content: '●';
  position: absolute;
  left: 0;
  top: 0;
  color: var(--garnet);
  font-size: 0.7em;
  line-height: 1.6;
}
@media (max-width: 900px) {
  .about-method-body .method-grid {
    grid-template-columns: 1fr;
    gap: 16px;
  }
}

/* ─────────────  v19.43-fix15: corpus-loading shield  ─────────────
   While ensureCorpusReady() is in flight (heavy 25 MB JSON.parse +
   FlexSearch.add ×7077), block result-row clicks so accidental taps
   don't queue setActive handlers that compound the memory peak and
   crash mobile Safari. The search input itself stays interactive so
   users can still type while the corpus streams in. */
body.is-corpus-loading .result[data-para-id],
body.is-corpus-loading .scope-opt,
body.is-corpus-loading .docs-rail-row,
body.is-corpus-loading .result-opt,
body.is-corpus-loading .dossier-context-para {
  pointer-events: none;
  opacity: 0.55;
  cursor: progress;
}
body.is-corpus-loading #q { cursor: progress; }

/* Mobile orientation toast — replaces the desktop tour on phones.
   Bottom-anchored, dismissible, auto-fades. */
.mobile-orient-toast {
  position: fixed;
  left: 12px;
  right: 12px;
  bottom: 12px;
  z-index: 80;
  padding: 14px 38px 14px 16px;
  background: var(--paper);
  border: 1px solid var(--garnet);
  border-left-width: 4px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.18);
  font-family: var(--display);
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink);
  animation: mobileToastIn 0.25s ease;
}
.mobile-orient-toast .folio { display: block; margin-bottom: 6px; font-size: 10px; }
.mobile-orient-toast p { margin: 6px 0 0; }
.mobile-orient-toast.is-out { opacity: 0; transition: opacity 0.25s ease; }
.mobile-orient-toast-close {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 26px;
  height: 26px;
  background: transparent;
  border: 0;
  color: var(--ink-3);
  font-size: 18px;
  cursor: pointer;
  line-height: 1;
}
@keyframes mobileToastIn {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ─────────────  RESPONSIVE  ───────────── */
@media (max-width: 1100px) {
  :root { --col-filters: 220px; --col-dossier: 300px; }
  .results { padding: 24px 24px 60px; }
}
/* v19.43-fix14: at narrow widths the app-shell (locked 100vh,
   nested overflow chain) is the wrong pattern — it fights iOS Safari
   viewport quirks and squeezes the 4-column layout into unusable
   slivers. Below 900 px we revert to natural document flow: body
   scrolls, panes stack, dossier becomes a fullscreen overlay. */
@media (max-width: 900px) {
  html, body {
    height: auto;
    min-height: 100vh;
    overflow: auto;
  }
  body { display: block; }
  /* v19.44-fix25: the previous `section[data-view] { display: block }`
     rule had equal specificity to `section[data-view] { display: none }`
     at line 2673 and overrode it (later in cascade), so on mobile EVERY
     view section was rendered simultaneously. The active-view rules
     (body[data-active-view=…] section[data-view=…]) only flipped the
     active one to flex/block — they never put the inactive ones back
     to none. Result: clicking Documents/Workspace/About set the hash
     and the body class but the search view stayed painted on top, so
     the new view never appeared.
     Fix: keep ALL inactive sections hidden on mobile too, but switch
     the active one to display:block (not flex — the layout grid is
     reverted to natural document flow on mobile so flex is wrong). */
  section[data-view] {
    display: none;
    flex: none;
    overflow: visible;
  }
  body[data-active-view="search"]    section[data-view="search"],
  body[data-active-view="documents"] section[data-view="documents"],
  body[data-active-view="workspace"] section[data-view="workspace"],
  body[data-active-view="about"]     section[data-view="about"] {
    display: block;
  }
  section[data-view="search"],
  section[data-view="documents"] {
    overflow: visible;
  }
  .layout {
    display: block;
    grid-template-columns: 1fr;
    grid-template-rows: auto;
    flex: none;
    overflow: visible;
  }
  .layout > .filters,
  .layout > .results,
  .layout > .dossier {
    height: auto;
    max-height: none;
    overflow: visible;
  }
  .filters {
    border-right: 0;
    border-bottom: 1px solid var(--rule);
    padding: 16px 20px;
  }
  .results { padding: 20px 20px 60px; }
  /* Drawer becomes a fullscreen overlay on narrow viewports — slides
     in over the results, dismissed via × or Esc as on desktop. */
  body:not(.dossier-collapsed) .dossier {
    position: fixed;
    inset: 0;
    z-index: 90;
    border-left: 0;
    background: var(--paper);
    overflow: hidden;       /* internal flex column owns scroll */
  }
  .dossier-resizer { display: none; }
  /* Documents view: stack rail above body, drop right drawer. */
  .docs-reader {
    display: block;
    grid-template-columns: 1fr;
    flex: none;
    overflow: visible;
  }
  .docs-reader > .docs-rail {
    height: auto;
    max-height: 240px;
    border-right: 0;
    border-bottom: 1px solid var(--rule);
  }
  .docs-reader > .docs-reader-body {
    height: auto;
    max-height: none;
    overflow: visible;
  }
  .docs-reader > .docs-drawer { display: none; }
  /* Mast collapses subtitle on phones to save vertical real estate. */
  .mast { padding: 10px 20px 8px; }
  .mast-title { font-size: 24px; }
  .mast-sub { display: none; }
  #mast-folio { font-size: 9px; }
  .mast-row {
    gap: 8px;
    flex-direction: column;     /* brand top, nav directly below — guaranteed visible */
    align-items: stretch;
  }
  /* v19.44-fix24: mobile nav was tap-blocked on iOS Safari because
     the link tap targets were ~22 px tall (font 13 px + 2 px padding-
     bottom). Below 700 px the nav now renders as a horizontal scroll-
     able pill row with 44 px-tall taps (Apple HIG minimum), separated
     from the title block by a hairline. */
  .mast-nav {
    gap: 6px;
    font-size: 13px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    padding-top: 8px;
    border-top: 1px solid var(--rule);
    flex-wrap: nowrap;
  }
  .mast-nav a {
    flex: 0 0 auto;
    min-height: 36px;
    padding: 8px 10px;
    line-height: 1;
    display: inline-flex;
    align-items: center;
  }
  .mast-nav a.active {
    background: var(--paper-3);
    border-bottom: 0;
    border-radius: 3px;
    color: var(--garnet);
  }
  .mast-tour-btn { display: none; }       /* save space; tour still reachable from welcome card */
  .mast-sep { display: none; }            /* nav is one row, no need for the separator */
  #theme-toggle {
    flex: 0 0 auto;
    min-height: 36px;
    margin-left: auto;
  }
  .searchbar { padding: 12px 20px; }
  .searchbar-inner { gap: 8px; flex-wrap: wrap; }
  .foot-inner { padding: 8px 20px; font-size: 10px; }

  /* v19.44-fix24: collapse the entire filter pane behind a single
     toggle on mobile. Researchers land → see results immediately
     (no need to scroll past 700 px of filter chrome). The toggle
     pill lives at the top of .filters and exposes the filters on
     demand. JS adds the .is-mobile-filters-collapsed body class on
     boot below 900 px (see initMobileFilterToggle). */
  .filters {
    border-bottom: 1px solid var(--rule);
    padding: 0;
  }
  .mobile-filters-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    background: var(--paper-2);
    border: 0;
    border-bottom: 1px solid var(--rule);
    padding: 12px 20px;
    font-family: var(--display);
    font-size: 13px;
    letter-spacing: 0.04em;
    color: var(--ink);
    cursor: pointer;
    text-align: left;
    min-height: 44px;
  }
  .mobile-filters-toggle .folio { font-size: 10px; color: var(--garnet); }
  .mobile-filters-toggle .chev { font-family: var(--mono); font-size: 11px; color: var(--ink-3); transition: transform .18s; }
  body.is-mobile-filters-collapsed .mobile-filters-toggle .chev { transform: rotate(-90deg); }
  .filters > .filter-block {
    padding-left: 20px;
    padding-right: 20px;
  }
  body.is-mobile-filters-collapsed .filters > .filter-block {
    display: none;
  }
}
@media (max-width: 600px) {
  /* Phone-only: tighter spacing, bigger touch targets. */
  .filter-block { margin-bottom: 16px; }
  .scope-opt { padding: 10px 12px; }
  .result { padding: 14px 0; }
  .dossier-cta { padding: 8px 14px; font-size: 13px; }
  .dossier-icon-btn { width: 40px; height: 40px; font-size: 18px; }
}
@media (max-width: 700px) {
  .results-tools { align-items: flex-start; }
  .result-actions {
    width: 100%;
    margin-left: 0;
  }
  .result-doc-details > summary {
    grid-template-columns: 14px 1fr;
  }
  .result-doc-summary-meta {
    grid-column: 2;
    justify-content: flex-start;
  }

  /* v19.43-fix17: mobile result row.
     The desktop grid (64 px margin · 1fr body · 130 px aside) leaves
     ~140 px for the body on a 390 px iPhone — text reflows to 2-3
     words per line ("The Convention / and the / Optional / Protocols"
     etc.). Drop the multi-column grid in favour of a stacked block
     layout: title row inline at top, paragraph text full-width,
     source + icons below. KWIC is line-clamped to 6 lines so long
     paragraphs don't dominate the viewport — Expand still uncovers
     the full text. */
  .result,
  .result.is-grouped-result {
    display: block;
    grid-template-columns: none;
    gap: 0;
    padding: 16px 0 18px;
  }
  .result.is-active {
    margin: 0 -12px;
    padding-left: 12px;
    padding-right: 12px;
  }
  .result-margin {
    display: inline-flex;
    align-items: baseline;
    gap: 10px;
    text-align: left;
    padding-top: 0;
    margin-bottom: 4px;
  }
  .result-rank {
    font-size: 10px;
    color: var(--ink-4);
  }
  .result-pn {
    font-size: 18px;
    margin-top: 0;
  }
  .result-headline {
    margin-bottom: 6px;
    font-size: 14px;
  }
  .result-doc {
    font-size: 14px;
    line-height: 1.3;
  }
  .result-text {
    font-size: 14px;
    line-height: 1.55;
    /* v19.43-fix17: clamp long snippets to 6 lines on mobile. Users
       see the matched cluster, can hit Expand for the full text. The
       desktop 30+ char-per-line layout already gives full prose; we
       only short-change phones to keep result rows scannable. */
    display: -webkit-box;
    -webkit-line-clamp: 6;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .result-text.is-expanded {
    -webkit-line-clamp: unset;
    display: block;
  }
  .result-aside {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    margin-top: 10px;
    padding-top: 8px;
    border-top: 1px dotted var(--rule);
  }
  .result-aside .folio { font-size: 9px; flex: 0 0 auto; }
  .result-aside .sig { font-size: 11px; flex: 1 1 auto; min-width: 0; }
  .result-marks {
    display: flex;
    gap: 4px;
    margin-left: auto;
  }

  /* v19.44-fix24: grouped-by-document view on mobile.
     The headline's `.result-spacer` (a 1-px dotted leader between
     "MATCHED PARAGRAPH" and the year) renders as a competing line
     against the result-aside's dotted top border + the row's solid
     bottom border, creating visual noise on phones (per user
     screenshot). Drop the leader on narrow screens — the year wraps
     to its own line which is what we want anyway. */
  .result-headline .result-spacer { display: none; }
  .result-headline .folio { margin-left: auto; }   /* push year to right edge */

  /* Tighter inter-result rhythm — fewer competing horizontal lines. */
  .result.is-grouped-result {
    padding: 12px 0 14px;
  }
  .result-list.is-grouped {
    border-bottom: 0;
  }
}

/* ─────────── Footnotes (v19.8) ───────────
   In-paragraph marker, popover, and "match in citation" pill. Designed
   to fit the Garamond + steel-grey aesthetic; markers stay subtle so they
   don't fight the text, popover sits above the rest of the chrome. */

.fn-marker {
  display: inline;
  border: 0;
  background: transparent;
  cursor: pointer;
  color: var(--garnet);
  font-family: var(--mono);
  font-size: inherit;
  padding: 0 1px;
  margin: 0 1px;
  line-height: 1;
  vertical-align: baseline;
  border-radius: 2px;
}
.fn-marker > sup {
  font-size: 0.72em;
  line-height: 1;
  font-feature-settings: "sups";
}
.fn-marker:hover,
.fn-marker:focus-visible {
  background: var(--paper-2);
  outline: 1px solid var(--garnet);
  outline-offset: 1px;
}
.fn-marker[aria-expanded="true"] {
  background: var(--garnet);
  color: var(--paper);
  outline: 0;
}

.fn-popover {
  position: absolute;
  z-index: 9000;
  max-width: 360px;
  min-width: 220px;
  background: var(--paper);
  border: 1px solid var(--rule);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.16);
  border-radius: 4px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink);
}
.fn-popover[hidden] { display: none; }
.fn-popover-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border-bottom: 1px solid var(--rule);
  background: var(--paper-2);
  border-top-left-radius: 4px;
  border-top-right-radius: 4px;
}
.fn-popover-head .folio {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  color: var(--garnet);
}
.fn-popover-n {
  font-size: 11px;
  color: var(--ink-soft);
}
.fn-popover-close {
  margin-left: auto;
  border: 0;
  background: transparent;
  cursor: pointer;
  font-size: 18px;
  line-height: 1;
  color: var(--ink-soft);
  padding: 0 4px;
}
.fn-popover-close:hover { color: var(--garnet); }
.fn-popover-body {
  padding: 8px 10px 10px;
  white-space: pre-wrap;
  font-style: italic;
}

.match-in-citation {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.04em;
  color: var(--garnet);
  background: var(--paper-2);
  padding: 1px 6px;
  border-radius: 3px;
  border: 1px dashed var(--garnet);
  margin-left: 6px;
}

@media (max-width: 600px) {
  /* Below 600px, the popover behaves like a bottom sheet — full width,
     anchored to bottom of viewport. We override the absolute positioning
     set by JS via !important since the JS measures viewport-relative. */
  .fn-popover {
    position: fixed !important;
    left: 8px !important;
    right: 8px !important;
    bottom: 8px !important;
    top: auto !important;
    max-width: none;
    width: auto;
  }
}

/* ─────────── v19.14: Per-paragraph feedback flow ───────────
   Adds a ⚐ button in the dossier toolbar and the documents reader
   paragraph row, plus a toast that appears after a successful submit
   and a char-counter on the comment textarea. */

/* In-paragraph "flag" affordance in the documents reader. Mirrors the
   adjacent .docs-para-cite styling. */
.docs-para-flag {
  border: 0;
  background: transparent;
  cursor: pointer;
  font-size: 14px;
  color: var(--ink-3);
  padding: 2px 4px;
  line-height: 1;
}
.docs-para-flag:hover { color: var(--garnet); }

/* Char counter on the comment textarea — sits below-right, dim. */
.report-charcount {
  align-self: flex-end;
  font-size: 10px;
  margin-top: 2px;
}

/* Email field is collapsed-by-default style (less prominent than the
   message field — it's optional + power-user). */
.report-field-collapsed { gap: 2px; }
.report-field-collapsed input {
  font-size: 12px;
  padding: 6px 8px;
}

/* Footer note links to the public feedback repo. */
.report-form .report-note a {
  color: var(--garnet);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* Toast for the post-submit success message. Anchored bottom-right,
   slides up + fades in. */
.feedback-toast {
  position: fixed;
  bottom: 24px;
  right: 24px;
  z-index: 9500;
  background: var(--paper);
  border: 1px solid var(--garnet);
  border-radius: 4px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.18);
  padding: 12px 14px;
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--body);
  font-size: 13px;
  color: var(--ink);
  max-width: 360px;
  opacity: 0;
  transform: translateY(12px);
  pointer-events: none;
  transition: opacity 220ms ease, transform 220ms ease;
}
.feedback-toast.is-shown {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}
.feedback-toast-mark {
  font-size: 16px;
  color: var(--garnet);
  font-weight: 700;
}
.feedback-toast-msg a {
  color: var(--garnet);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.feedback-toast-close {
  border: 0;
  background: transparent;
  cursor: pointer;
  font-size: 18px;
  color: var(--ink-3);
  padding: 0 4px;
  line-height: 1;
  margin-left: auto;
}
.feedback-toast-close:hover { color: var(--garnet); }

@media (max-width: 600px) {
  .feedback-toast {
    left: 8px;
    right: 8px;
    bottom: 8px;
    max-width: none;
  }
}

/* ───────────────────────── Ask tab (v19.55) ─────────────────────────
   Extractive RAG view. Styles use design tokens so dark-mode + theme
   switches Just Work; no hard-coded hex colours. */
body[data-active-view="ask"] section[data-view="ask"] {
  display: flex; flex-direction: column; flex: 1 1 0;
  min-height: 0; overflow-y: auto; padding-bottom: 4rem;
}
.ask-disclaimer {
  /* v19.55.2 user preference: yellow advisory, not garnet-red.
     Uses the existing vellum-yellow highlight token so dark mode
     and theme switches stay coherent. */
  background: var(--hl);
  border-left: 4px solid var(--hl-edge);
  padding: 0.75rem 1rem; margin: 1rem 1.5rem;
  border-radius: 4px;
  font-size: 0.92rem; line-height: 1.5;
  color: var(--ink);
}
.ask-disclaimer .about-link {
  color: var(--garnet); text-decoration: underline;
}
.ask-controls-details {
  margin: 0.5rem 1.5rem 0; font-size: 0.88rem;
}
.ask-controls-details > summary {
  color: var(--ink-3); cursor: pointer;
  font-family: var(--display); letter-spacing: 0.02em;
  padding: 0.25rem 0; user-select: none;
}
.ask-controls-details > summary:hover { color: var(--garnet); }
.ask-controls {
  display: flex; align-items: center; gap: 0.5rem;
  margin-top: 0.4rem; color: var(--ink-3);
}
.ask-controls label { display: inline-flex; align-items: center; gap: 0.4rem; }
.ask-controls input[type="number"] {
  width: 4rem; padding: 0.25rem 0.4rem;
  border: 1px solid var(--rule); border-radius: 4px; font: inherit;
  background: var(--paper);
}
.ask-controls-hint { opacity: 0.7; }
.ask-meta {
  font-size: 0.78rem; color: var(--ink-4);
  margin: 0 1.5rem 0.5rem;
}
.ask-answer {
  background: var(--paper-2);
  border-left: 4px solid var(--garnet);
  padding: 1rem 1.25rem; margin: 1rem 1.5rem;
  border-radius: 4px;
}
.ask-answer-title {
  font-weight: 700; font-size: 0.9rem; margin-bottom: 0.25rem;
  color: var(--garnet); letter-spacing: 0.04em;
  font-family: var(--display); text-transform: uppercase;
}
.ask-answer-hint {
  font-size: 0.82rem; color: var(--ink-3);
  margin-bottom: 0.55rem; font-style: italic;
}
.ask-answer-body { white-space: pre-wrap; line-height: 1.55; color: var(--ink); }

/* v19.55.10: source context line — committee · GC title (year) +
   "Covenant"/"Convention" disambiguation hint. Sits between the
   "first-ranked paragraph below" sub-hint and the verbatim text. */
.ask-answer-source {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem 0.55rem;
  padding: 0.5rem 0.7rem;
  margin: 0 0 0.6rem;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 4px;
  font-size: 0.86rem;
}
.ask-answer-source-committee {
  font-family: var(--display);
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--garnet);
  font-size: 0.78rem;
  text-transform: uppercase;
}
.ask-answer-source-title {
  color: var(--ink);
  font-weight: 600;
  font-family: var(--display);
}
.ask-answer-source-year {
  color: var(--ink-3);
  font-size: 0.82rem;
}
.ask-answer-source-hint {
  flex-basis: 100%;
  margin-top: 0.2rem;
  font-size: 0.8rem;
  color: var(--ink-3);
  font-style: italic;
}
.ask-answer-source-hint strong {
  font-style: normal;
  color: var(--ink-2);
}

/* v19.55.10 Phase 1.5: inline treaty annotations + popover.
   Only article-number citations now get visible treatment ("article 4(2)"
   becomes a clickable button that opens a popover with the actual treaty
   article text). The "the Covenant[ICCPR]" sup-abbr badge was removed
   in v19.56.5 — it looked like edited text, and the committee column
   on the dossier already tells the reader which convention they're in.
   Rules kept commented for the historical record. */
/* .treaty-term { } */
/* .treaty-term-abbr { display: inline-block; vertical-align: super;
     ...see git history at v19.56.4 for the original rule. } */
.treaty-article-ref {
  display: inline;
  padding: 0 0.18em;
  margin: 0 0.05em;
  background: transparent;
  border: none;
  border-bottom: 1px dashed var(--garnet);
  color: var(--garnet);
  cursor: pointer;
  font: inherit;
  line-height: inherit;
}
.treaty-article-ref:hover,
.treaty-article-ref:focus-visible {
  background: var(--paper-2, #f4eee5);
  outline: none;
  border-bottom-style: solid;
}
.treaty-popover {
  display: none;
  z-index: 1000;
  width: 420px;
  max-width: 90vw;
  max-height: 60vh;
  overflow-y: auto;
  background: var(--paper, #fbf7f0);
  border: 1px solid var(--rule);
  border-radius: 6px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
  font-size: 0.88rem;
  line-height: 1.5;
}
.treaty-popover-header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.55rem 0.75rem;
  background: var(--paper-2);
  border-bottom: 1px solid var(--rule);
  font-family: var(--display);
  /* v19.56.6: pin the header to the top of the scrollable popover so
     the user always sees which treaty + article the body refers to,
     even after scrolling through a long article (e.g. ICCPR art. 14
     which has many paragraphs). The popover container itself is the
     scroll-y container (overflow-y: auto + max-height: 60vh on
     .treaty-popover), so position:sticky / top:0 is anchored to it. */
  position: sticky;
  top: 0;
  z-index: 2;
}
.treaty-popover-abbr {
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--garnet);
  font-size: 0.78rem;
  text-transform: uppercase;
}
.treaty-popover-art {
  font-weight: 600;
  color: var(--ink);
  flex-grow: 1;
}
.treaty-popover-close {
  background: transparent;
  border: none;
  color: var(--ink-3);
  cursor: pointer;
  font-size: 1.3rem;
  line-height: 1;
  padding: 0 0.3rem;
}
.treaty-popover-close:hover { color: var(--garnet); }
.treaty-popover-body {
  padding: 0.6rem 0.85rem;
  color: var(--ink);
}
.treaty-popover-para {
  margin: 0 0 0.55rem;
}
.treaty-popover-para:last-child { margin-bottom: 0; }
.treaty-popover-para strong {
  color: var(--ink-2);
  margin-right: 0.15em;
}
.treaty-popover-source {
  padding: 0.4rem 0.85rem;
  border-top: 1px solid var(--rule);
  font-size: 0.75rem;
  color: var(--ink-3);
  font-style: italic;
  /* v19.56.6: pin the source line to the bottom of the scrollable
     popover so the treaty's full name remains visible while the user
     scrolls through long articles. Mirrors the sticky header. */
  position: sticky;
  bottom: 0;
  background: var(--paper, #fbf7f0);
  z-index: 2;
}
.ask-sources-title {
  font-family: var(--display); font-weight: 700; font-size: 1.05rem;
  margin: 1.5rem 1.5rem 0.5rem;
  color: var(--ink);
}
.ask-source {
  background: var(--paper);
  border: 1px solid var(--rule);
  padding: 0.85rem 1rem; margin: 0.5rem 1.5rem;
  border-radius: 6px; cursor: pointer;
  transition: border-color .15s, box-shadow .15s;
}
.ask-source:hover {
  border-color: var(--garnet);
  box-shadow: 0 2px 6px var(--garnet-soft);
}
.ask-source:focus { outline: 2px solid var(--garnet); outline-offset: 2px; }
.ask-source-meta {
  font-size: 0.85rem; color: var(--ink-3);
  margin-bottom: 0.4rem;
  display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center;
}
.ask-citation { font-weight: 700; color: var(--garnet); }
.ask-status-superseded {
  background: var(--garnet-soft); color: var(--garnet-2);
  padding: 1px 6px; border-radius: 999px;
  font-size: 0.72rem; font-weight: 700;
}
.ask-score {
  padding: 2px 8px; border-radius: 999px;
  font-size: 0.72rem; font-weight: 700; margin-left: auto;
}
.ask-score-excellent { background: oklch(94% 0.05 145); color: oklch(35% 0.10 145); }
.ask-score-good      { background: oklch(94% 0.04 220); color: oklch(40% 0.10 220); }
.ask-score-medium    { background: var(--hl); color: oklch(35% 0.08 80); }
.ask-score-weak,
.ask-score-very      { background: var(--garnet-soft); color: var(--garnet-2); }
.ask-source-title    { font-weight: 600; color: var(--ink); }
.ask-source-header   { font-size: 0.85rem; color: var(--ink-3); margin-top: .25rem; }
.ask-source-articles {
  font-size: 0.8rem; color: var(--ink-3);
  margin-top: .25rem;
  font-variant: small-caps; letter-spacing: 0.02em;
}
.ask-source-text { margin-top: 0.5rem; line-height: 1.55; color: var(--ink); }
.ask-source-text mark { background: var(--hl); padding: 0 2px; }
.ask-source-open-hint {
  font-size: 0.75rem; color: var(--garnet);
  margin-top: 0.5rem; opacity: 0.6;
}
.ask-source:hover .ask-source-open-hint { opacity: 1; }

/* v19.55.10: per-source action toolbar — Copy / Cite / Bookmark / UN.
   Inline at the bottom of each source card so a researcher doesn't
   need to round-trip through the dossier drawer for routine actions. */
.ask-source-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.5rem;
  margin-top: 0.6rem;
  padding-top: 0.5rem;
  border-top: 1px dashed var(--rule);
}
.ask-source-act {
  display: inline-flex;
  align-items: center;
  gap: 0.25em;
  padding: 0.25rem 0.55rem;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 4px;
  color: var(--ink-2);
  font-family: var(--display);
  font-size: 0.78rem;
  cursor: pointer;
  text-decoration: none;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
  white-space: nowrap;
}
.ask-source-act:hover,
.ask-source-act:focus-visible {
  background: var(--paper-2);
  border-color: var(--garnet);
  color: var(--garnet);
  outline: none;
}
.ask-source-act-bm.is-on {
  background: var(--paper-2);
  border-color: var(--garnet);
  color: var(--garnet);
}
.ask-source-act.is-flash-ok {
  background: var(--garnet-soft, #f0e0e0);
  border-color: var(--garnet);
  color: var(--garnet);
}
.ask-source-act.is-flash-err {
  background: #fff3e0;
  border-color: #c46f00;
  color: #c46f00;
}
.ask-source-act-link::after {
  /* small visual hint for "leaves the app" */
  content: '';
}
.ask-source-act-hint {
  font-size: 0.72rem;
  font-style: italic;
  margin-left: 0.2rem;
}
.ask-source-act-dossier {
  margin-left: auto;   /* pushes the dossier button to the right edge */
  background: var(--paper-2);
  border-color: var(--rule);
  color: var(--ink-2);
}
.ask-source-act-dossier:hover,
.ask-source-act-dossier:focus-visible {
  border-color: var(--garnet);
  color: var(--garnet);
}
.ask-source-act-sub {
  font-size: 0.72rem;
  font-style: italic;
  font-weight: normal;
  color: var(--ink-3);
  margin-left: 0.3rem;
}
.ask-loading {
  padding: 2rem; text-align: center;
  color: var(--ink-3); font-style: italic;
}
.ask-empty-hint {
  padding: 1rem 1.5rem;
  margin: 0.5rem 1.5rem;
  color: var(--ink-3);
  background: var(--paper-2);
  border-left: 3px solid var(--rule);
  border-radius: 4px;
  font-size: 0.9rem;
  line-height: 1.5;
}

/* BETA / experimental tagging.  Two surfaces:
   1. nav badge next to "Ask" link — small inline pill
   2. tab-level banner above the ask form — wider, more visible */
.nav-beta-badge {
  display: inline-block;
  margin-left: 0.35em;
  padding: 0.05em 0.4em;
  background: var(--garnet, #9b1d1d);
  color: white;
  font-family: var(--mono, monospace);
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  border-radius: 3px;
  vertical-align: super;
  line-height: 1.4;
}
.about-method-toc .nav-beta-badge,
.about-method-summary-title .nav-beta-badge {
  vertical-align: baseline;
}
.ask-beta-banner {
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
  padding: 0.8rem 1.1rem;
  margin: 0.4rem 1.5rem 0.8rem;
  background: #fff3df;
  border: 1px solid #d6a85a;
  border-left: 4px solid #b8861f;
  border-radius: 4px;
  font-size: 0.86rem;
  line-height: 1.5;
  color: var(--ink);
}
.ask-beta-tag {
  display: inline-block;
  flex-shrink: 0;
  padding: 0.18rem 0.55rem;
  background: #b8861f;
  color: white;
  font-family: var(--mono, monospace);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  border-radius: 3px;
  white-space: nowrap;
  margin-top: 0.1rem;
}
.ask-beta-text {
  flex-grow: 1;
}
.ask-beta-text p {
  margin: 0;
}
.ask-beta-text p + p {
  margin-top: 0.45rem;
}
.ask-beta-meta {
  font-size: 0.8rem;
  color: var(--ink-3);
  font-style: italic;
}
.ask-beta-meta a {
  font-style: normal;
}
.ask-error {
  padding: 1rem 1.5rem;
  color: var(--garnet-2); background: var(--garnet-soft);
  border-left: 4px solid var(--garnet);
  margin: 1rem 1.5rem; border-radius: 4px;
}
/* Drawer slot — reuses the existing #dossier element by re-parenting. */
.ask-drawer {
  position: fixed; top: 0; right: 0;
  width: min(560px, 92vw); height: 100vh;
  z-index: 1000; transform: translateX(100%);
  transition: transform .22s ease-out;
  background: var(--paper);
  border-left: 1px solid var(--rule);
  box-shadow: -8px 0 24px rgba(0, 0, 0, 0.12);
  display: flex; flex-direction: column;
}
.ask-drawer.is-open { transform: translateX(0); }
.ask-drawer-backdrop {
  position: fixed; inset: 0;
  background: rgba(0, 0, 0, 0.18);
  z-index: 999; opacity: 0; pointer-events: none;
  transition: opacity .22s;
}
.ask-drawer-backdrop.is-open { opacity: 1; pointer-events: auto; }
.ask-drawer #dossier {
  flex: 1 1 auto; max-width: none; min-width: 0;
  height: 100%; border-left: none; box-shadow: none;
}

/* v19.55.1: per-source "why this matched" + cited-corpus footer. */
.ask-why {
  margin-top: 0.6rem;
  font-size: 0.82rem;
  color: var(--ink-3);
  border-top: 1px dashed var(--rule-soft);
  padding-top: 0.45rem;
}
.ask-why > summary {
  cursor: pointer;
  color: var(--ink-3);
  font-family: var(--display);
  letter-spacing: 0.02em;
  user-select: none;
  padding: 0.1rem 0;
}
.ask-why > summary:hover { color: var(--garnet); }
.ask-why-body { padding: 0.4rem 0 0.1rem; }
.ask-why-row {
  margin: 0.2rem 0;
  line-height: 1.45;
}
.ask-why-row.dim { color: var(--ink-4); font-style: italic; }
.ask-why-label {
  display: inline-block;
  min-width: 7.5em;
  font-variant: small-caps;
  letter-spacing: 0.02em;
  color: var(--ink-2);
  font-weight: 600;
}
.ask-cited {
  margin: 1.2rem 1.5rem 0;
  font-size: 0.88rem;
  color: var(--ink-2);
  border-top: 1px solid var(--rule-soft);
  padding-top: 0.6rem;
}
.ask-cited > summary {
  cursor: pointer;
  font-family: var(--display);
  letter-spacing: 0.02em;
  color: var(--ink-2);
  padding: 0.25rem 0;
  user-select: none;
}
.ask-cited > summary:hover { color: var(--garnet); }
.ask-cited > summary strong { color: var(--garnet); }
.ask-cited-list {
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0;
  font-size: 0.85rem;
  color: var(--ink-2);
}
.ask-cited-list li {
  padding: 0.18rem 0;
  border-bottom: 1px dashed var(--rule-soft);
}
.ask-cited-list li:last-child { border-bottom: none; }
.ask-cited-list .dim { color: var(--ink-3); }

/* v19.55.2 P2 #7: Ask filter chips. Mirrors Search's filter idiom
   but kept self-contained so Ask can evolve independently. Uses
   design tokens — dark mode works without changes. */
.ask-filters {
  margin: 0.5rem 1.5rem 0;
  padding: 0.5rem 0.75rem;
  background: var(--paper-2);
  border: 1px solid var(--rule-soft);
  border-radius: 6px;
  font-size: 0.85rem;
}
.ask-filters-row {
  display: flex; flex-wrap: wrap;
  align-items: center; gap: 0.4rem 0.6rem;
  padding: 0.2rem 0;
}
.ask-filters-row + .ask-filters-row {
  margin-top: 0.3rem; padding-top: 0.4rem;
  border-top: 1px dashed var(--rule-soft);
}
.ask-filters-label {
  font-family: var(--display);
  font-variant: small-caps;
  letter-spacing: 0.04em;
  color: var(--ink-3);
  min-width: 6.2em;
  font-weight: 600;
}
.ask-filters-dash { color: var(--ink-4); padding: 0 0.1rem; }
.ask-filters input[type="number"] {
  width: 5rem;
  padding: 0.2rem 0.4rem;
  border: 1px solid var(--rule);
  border-radius: 4px;
  font: inherit;
  background: var(--paper);
  color: var(--ink);
}
.ask-filter-superseded {
  display: inline-flex; align-items: center; gap: 0.4rem;
  margin-left: 0.5rem;
  color: var(--ink-3);
  cursor: pointer;
  user-select: none;
}
.ask-filter-superseded input[type="checkbox"] {
  margin: 0; cursor: pointer;
}
.ask-chip {
  font: inherit;
  padding: 0.2rem 0.65rem;
  border: 1px solid var(--rule);
  border-radius: 999px;
  background: var(--paper);
  color: var(--ink-3);
  cursor: pointer;
  transition: all 0.12s ease-out;
  user-select: none;
  font-variant: small-caps;
  letter-spacing: 0.04em;
}
.ask-chip:hover {
  border-color: var(--garnet);
  color: var(--garnet);
}
.ask-chip.is-active {
  background: var(--garnet);
  color: var(--paper);
  border-color: var(--garnet);
}
.ask-chip.is-active:hover {
  background: var(--garnet-2);
}
.ask-chip-count {
  margin-left: 0.3rem;
  opacity: 0.6;
  font-size: 0.78rem;
}
.ask-filters-clear {
  margin-left: auto;
  font: inherit;
  font-size: 0.78rem;
  background: transparent;
  border: none;
  color: var(--garnet);
  cursor: pointer;
  text-decoration: underline;
  padding: 0.2rem 0.3rem;
  font-variant: small-caps;
  letter-spacing: 0.04em;
}
.ask-filters-clear:hover { color: var(--garnet-2); }

/* v19.55.3 P4 #12: counter-evidence section + pushback checkbox. */
.ask-filter-pushback {
  display: inline-flex; align-items: center; gap: 0.4rem;
  color: var(--ink-3);
  cursor: pointer;
  user-select: none;
}
.ask-filter-pushback input[type="checkbox"] { margin: 0; cursor: pointer; }
.ask-filters-cost-hint {
  font-size: 0.72rem;
  font-style: italic;
  color: var(--ink-4);
  margin-left: 0.3rem;
}
.ask-counter-section {
  margin: 2rem 1.5rem 0.5rem;
  padding-top: 1rem;
  border-top: 2px solid var(--rule);
}
.ask-counter-title {
  font-family: var(--display);
  font-size: 1.05rem;
  font-weight: 700;
  margin: 0 0 0.3rem;
  color: var(--ink);
}
.ask-counter-title::before {
  content: '⚖';
  margin-right: 0.4rem;
  color: var(--garnet);
  font-weight: normal;
}
.ask-counter-hint {
  font-size: 0.85rem;
  line-height: 1.5;
  color: var(--ink-3);
  margin: 0 0 0.8rem;
  max-width: 56em;
}
.ask-source.is-counter {
  /* Visual distinction without being heavy-handed: thin teal accent
     that signals "this is the other side" without crowding the main
     reading rhythm. */
  border-left: 3px solid var(--jur-tone);
  background: linear-gradient(to right, var(--jur-soft) 0, var(--paper) 60%);
}
.ask-source.is-counter:hover {
  border-color: var(--jur-tone);
  box-shadow: 0 2px 6px var(--jur-soft);
}
.ask-counter-empty {
  font-style: italic;
  color: var(--ink-3);
  padding: 0.8rem 1rem;
  background: var(--paper-2);
  border-radius: 6px;
  margin: 0 0 0.5rem;
  font-size: 0.9rem;
}

/* v19.55.6: HyDE-interpretation panel — "How your question was interpreted".
   Open by default (single biggest trust signal in the tab); user can
   collapse. Different visual treatment from regular sources so it
   reads clearly as meta-info. */
.ask-hyde {
  margin: 0.6rem 1.5rem 0;
  padding: 0.7rem 1rem;
  background: var(--paper-2);
  border-left: 4px solid var(--ink-3);
  border-radius: 4px;
  font-size: 0.9rem;
}
.ask-hyde > summary {
  cursor: pointer;
  font-family: var(--display);
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--ink-2);
  user-select: none;
  text-transform: uppercase;
  font-size: 0.82rem;
}
.ask-hyde > summary:hover { color: var(--garnet); }
.ask-hyde-body {
  margin-top: 0.5rem;
  color: var(--ink);
}
.ask-hyde-hint {
  font-size: 0.85rem;
  color: var(--ink-3);
  margin: 0 0 0.6rem;
  line-height: 1.5;
}
.ask-hyde-quote {
  font-family: var(--display);
  font-style: italic;
  margin: 0;
  padding: 0.5rem 0.8rem;
  border-left: 2px solid var(--rule);
  color: var(--ink);
  line-height: 1.6;
}

/* v19.55.8: HyDE Tier-1 UX rework — show extracted doctrinal terms
   as chips instead of leading with the full hypothetical paragraph.
   The chip row is the headline; the full probe is a nested toggle. */
.ask-hyde-terms-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem 0.5rem;
  margin: 0 0 0.6rem;
}
.ask-hyde-terms-label {
  font-family: var(--display);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.ask-hyde-terms {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0.35rem;
}
.ask-hyde-term {
  display: inline-block;
  padding: 0.15rem 0.55rem;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 999px;
  font-size: 0.82rem;
  font-family: var(--display);
  color: var(--ink);
  line-height: 1.4;
  white-space: nowrap;
}
/* v19.55.9: clickable expansion suggestions — alternative doctrinal
   framings the LLM produced. Click replaces query and re-runs ask. */
.ask-hyde-expansions-row {
  margin: 0.5rem 0 0.6rem;
}
.ask-hyde-expansions {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  margin-top: 0.35rem;
}
.ask-hyde-expansion {
  display: block;
  text-align: left;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 4px;
  padding: 0.4rem 0.65rem;
  font-family: var(--display);
  font-size: 0.86rem;
  font-style: italic;
  color: var(--ink);
  line-height: 1.45;
  cursor: pointer;
  transition: border-color 0.12s, background 0.12s;
  width: 100%;
}
.ask-hyde-expansion:hover,
.ask-hyde-expansion:focus-visible {
  border-color: var(--garnet);
  background: var(--paper-2);
  outline: none;
}
.ask-hyde-expansion::before {
  content: '↻ ';
  color: var(--ink-3);
  font-style: normal;
  font-weight: 600;
  margin-right: 0.2rem;
}

.ask-hyde-probe {
  margin-top: 0.6rem;
  padding-top: 0.5rem;
  border-top: 1px dashed var(--rule);
}
.ask-hyde-probe > summary {
  cursor: pointer;
  font-size: 0.78rem;
  font-family: var(--display);
  letter-spacing: 0.03em;
  color: var(--ink-3);
  user-select: none;
}
.ask-hyde-probe > summary:hover { color: var(--garnet); }
.ask-hyde-probe[open] > summary { color: var(--ink-2); }
.ask-hyde-probe > .ask-hyde-quote {
  margin-top: 0.5rem;
  font-size: 0.85rem;
}

/* v19.55.7: HyDE "unavailable" variant — different visual weight
   so it reads as "this feature is offline" rather than equal-status
   to a successful interpretation. Dimmer left rule, smaller summary. */
.ask-hyde.ask-hyde-unavailable {
  border-left-color: var(--rule);
  background: transparent;
  padding-left: 0.85rem;
}
.ask-hyde.ask-hyde-unavailable > summary {
  color: var(--ink-3);
  font-weight: 600;
  text-transform: none;
  font-size: 0.85rem;
  letter-spacing: 0;
  font-style: italic;
}
.ask-hyde.ask-hyde-unavailable > summary::before {
  content: '⚠ ';
  color: var(--preview, #945000);
}

/* v19.56: ISO-3166 alpha-2 country code badge — appears next to the
   country name in the doc reader head and dossier. Small mono pill. */
.country-code {
  display: inline-block;
  background: var(--paper-2, #f0ece4);
  color: var(--ink-3, #555);
  padding: 1px 6px;
  border-radius: 3px;
  font-size: 0.78em;
  letter-spacing: 0.04em;
  margin-left: 0.35em;
  vertical-align: baseline;
}
