/* Page-specific component styles on top of design.css.
   Library list rows + pagination; item detail header / banners /
   note-block / highlights / summary / image grid / inline body. */

/* =================================================================
   Library list (templates/library/library.html)
   ================================================================= */

.library-header {
  display: flex; align-items: center; gap: 16px;
  margin-bottom: 28px;
  flex-wrap: wrap;
}
.library-header h1 {
  font-family: var(--font-sans); font-weight: 500;
  font-size: 22px; line-height: 1.2; margin: 0;
  color: var(--ink-soft);
  letter-spacing: -0.005em;
}
.library-header .count {
  font-family: var(--font-sans); font-size: 13px;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}
.library-header .actions { margin-left: auto; display: flex; gap: 8px; flex-wrap: wrap; }

.items { display: flex; flex-direction: column; }
.item {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 4px 16px;
  padding: 18px 12px;
  border-radius: var(--radius-sm);
  border-bottom: 1px solid var(--paper-edge);
}
.item:last-child { border-bottom: 0; }
.item:hover {
  background: var(--highlight-faint);
  border-bottom-color: transparent;
}
.item .head {
  display: flex; align-items: center; gap: 10px;
  min-width: 0;
}
.item .title {
  font-family: var(--font-sans); font-weight: 500;
  font-size: 16px; line-height: 1.3; color: var(--ink-soft);
  text-decoration: none;
  letter-spacing: -0.005em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  min-width: 0;
}
.item .title:hover { color: var(--ink); }
.item .title:hover .title-text {
  box-shadow: inset 0 -0.4em 0 var(--highlight-wash);
}

/* "Threads" strip on the item detail page (spec 0014 PR2): cross-item
   navigation handles via shared named entities. Same hover treatment as
   .item .title — dark text, no underline, yellow wash on hover via the
   inset box-shadow trick on the inner span. The entity-detail page
   reuses .thread-link for its item list. */
.threads { margin: 8px 0 18px; }
.threads-label {
  font-family: var(--font-sans);
  color: var(--ink-muted);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-right: 8px;
}
.thread-link {
  font-family: var(--font-sans);
  font-weight: 500;
  color: var(--ink-soft);
  text-decoration: none;
  margin-right: 14px;
}
.thread-link:hover { color: var(--ink); }
.thread-link:hover .thread-link-text {
  box-shadow: inset 0 -0.4em 0 var(--highlight-wash);
}
/* Concept-tag rows (spec 0023 framing card) reuse .thread-link inline, but
   here the links are punctuated by commas / pipes rather than spaced as
   standalone nav handles — drop the strip's margin-right so punctuation hugs. */
.concept-row .thread-link { margin-right: 0; }
.item .untitled {
  font-family: var(--font-sans); font-size: 13px;
  color: var(--ink-faint); font-style: italic;
}
.item .meta-row {
  display: flex; align-items: center; gap: 10px;
  font-family: var(--font-sans); font-size: 12px; color: var(--ink-faint);
  grid-column: 1 / 2;
  flex-wrap: wrap;
}
.item .meta-row .when { display: inline-flex; align-items: center; gap: 5px; }
.item .meta-row .dot { color: var(--ink-ghost); }
.item .meta-row .progress { display: inline-flex; align-items: center; gap: 6px; font-variant-numeric: tabular-nums; }
.item .meta-row .progress .pct { color: var(--ink-muted); font-weight: 500; }

.item .summary {
  grid-column: 1 / -1;
  font-family: var(--font-serif);
  font-size: 16px; line-height: 1.5;
  color: var(--ink-soft);
  margin-top: 6px;
}
.item a.summary {
  text-decoration: none;
  display: block;
}
.item a.summary:hover { color: var(--ink); }

.item .row-actions {
  grid-row: 1;
  grid-column: 2;
  display: flex; gap: 2px;
  align-self: start;
}
.item form.row-form { margin: 0; padding: 0; display: inline; }
.item form.row-form button[type="submit"] { margin: 0; padding: 0; }

.pagination {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px;
  margin-top: 24px;
  padding: 12px 12px 0;
}
.pagination .indicator {
  font-family: var(--font-sans); font-size: 13px;
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}
.pagination .controls { display: flex; gap: 6px; }
.page-btn {
  font-family: var(--font-sans); font-size: 13px; font-weight: 500;
  color: var(--ink); background: var(--paper-raised);
  border: 1px solid var(--paper-edge);
  border-radius: var(--radius-sm);
  padding: 6px 12px;
  display: inline-flex; align-items: center; gap: 6px;
  cursor: pointer;
  text-decoration: none;
  transition: background var(--dur-fast) ease;
}
.page-btn:hover { background: var(--paper-sunken); }
.page-btn.disabled {
  color: var(--ink-faint);
  background: var(--paper);
  border-color: var(--paper-edge);
  cursor: default;
  pointer-events: none;
}

.empty {
  font-family: var(--font-serif);
  font-size: 19px; line-height: 1.55;
  color: var(--ink-muted);
  margin: 32px 0;
  max-width: 60ch;
}
.empty a { color: var(--ink); text-decoration-color: var(--highlight); }


/* =================================================================
   Item detail (templates/library/item_detail.html)
   ================================================================= */

.doc {
  max-width: 720px;
  margin: 0 auto;
  padding: 56px 32px 140px;
}

/* ---------- Metadata rail + inline panel (design refresh) ----------
   Mobile-first: single column. The rail is hidden; the collapsed inline
   panel (.meta-inline) carries the metadata above the summary. On wide
   screens the rail lifts into a persistent left column and the inline
   panel is hidden. */
.rail-col { display: none; }

/* Shared atoms (rail + inline). */
.md-sec + .md-sec { margin-top: 28px; }
.md-chips { display: flex; flex-wrap: wrap; gap: 8px; }

/* Entity chip — filled link to the entity page. */
.md-ent {
  display: inline-flex; align-items: baseline;
  font-family: var(--font-sans); font-size: 13px; font-weight: 500;
  color: var(--ink-soft); background: var(--paper-sunken);
  border: 1px solid transparent; padding: 4px 10px; border-radius: 5px;
  text-decoration: none;
  transition: background var(--dur-fast) ease, border-color var(--dur-fast) ease;
}
.md-ent:hover { background: var(--paper-edge); border-color: var(--paper-edge); }

/* Concept chip — outlined link to the concept page. */
.md-con {
  display: inline-flex; align-items: center;
  font-family: var(--font-sans); font-size: 13px; color: var(--ink-muted);
  background: transparent; border: 1px solid var(--paper-edge);
  padding: 4px 10px; border-radius: 5px; text-decoration: none;
  transition: color var(--dur-fast) ease, border-color var(--dur-fast) ease, background var(--dur-fast) ease;
}
.md-con:hover { color: var(--ink); border-color: var(--ink-ghost); background: var(--paper-raised); }
/* Unclustered concept (spec 0034): present in the item but not a link — it
   shares no neighborhood, so there's nowhere to go. Neutralize the link hover. */
.md-con-static { cursor: default; }
.md-con-static:hover { color: var(--ink-muted); border-color: var(--paper-edge); background: transparent; }
/* "× N" item count on a shared-concept chip — spaced, muted, not a pill. */
.md-con-count {
  margin-left: 5px; color: var(--ink-faint); font-weight: 500;
  font-variant-numeric: tabular-nums;
}
/* Divider between the shared and unique concept groups — the same light grey
   1px line used elsewhere in the rail (matches `.divider`). */
.md-con-divider {
  border: 0; border-top: 1px solid var(--paper-edge);
  height: 0; margin: 12px 0;
}

/* Character — label + Similar on a line, serif descriptor below. */
.md-char .row { padding: 13px 0; border-top: 1px solid var(--paper-edge); }
.md-char .row:first-child { border-top: 0; padding-top: 2px; }
.md-char .rowhead {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; margin-bottom: 5px;
}
.md-char .lab {
  font-family: var(--font-sans); font-size: 11px; font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-faint);
}
.md-char .val {
  font-family: var(--font-serif); font-size: 15px; line-height: 1.5;
  color: var(--ink-soft); margin: 0;
}
.md-sim {
  font-family: var(--font-sans); font-size: 12px; font-weight: 500; color: var(--ink-muted);
  text-decoration: none; white-space: nowrap;
  border-bottom: 1px solid transparent; padding-bottom: 1px;
  transition: color var(--dur-fast) ease, border-color var(--dur-fast) ease;
}
.md-sim:hover { color: var(--ink); border-bottom-color: var(--highlight); }

/* Rail keeps descriptors short so the persistent column stays compact. */
.md.is-rail .md-char .val {
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.md.is-rail .md-char .row.voice .val { -webkit-line-clamp: 4; }

/* Figures — compact thumbnail grid. Rail is 2-up, inline panel is 3-up. */
.md-figs { display: grid; gap: 6px; }
.md.is-rail .md-figs { grid-template-columns: repeat(2, 1fr); }
.md.is-inline .md-figs { grid-template-columns: repeat(3, 1fr); }
.md-fig { display: block; text-decoration: none; }
.md-fig .frame {
  aspect-ratio: 4 / 3; background: #fff;
  border: 1px solid var(--paper-edge); border-radius: 2px;
  overflow: hidden; display: flex; align-items: center; justify-content: center;
  transition: border-color var(--dur-fast) ease;
}
.md-fig:hover .frame { border-color: var(--ink-ghost); }
.md-fig .frame img { width: 100%; height: 100%; object-fit: cover; display: block; }
.md-fig.more .frame {
  border-style: dashed; background: var(--paper);
  flex-direction: column; gap: 1px;
}
.md-fig.more .more-n {
  font-family: var(--font-sans); font-size: 13px; font-weight: 600;
  color: var(--ink-muted); line-height: 1;
}
.md-fig.more .more-lbl {
  font-family: var(--font-sans); font-size: 9px; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--ink-faint);
}
.md-fig.more:hover .frame { border-color: var(--ink-muted); background: var(--highlight-faint); }

/* Inline collapsible panel (narrow screens only). */
.meta-inline {
  margin: 4px 0 36px;
  border-top: 1px solid var(--paper-edge);
  border-bottom: 1px solid var(--paper-edge);
}
/* When the panel sits directly after the framing divider (no note/highlights
   between), the divider already draws the top rule — drop the panel's own so
   the two don't stack into a double line on mobile. */
.divider + .meta-inline { border-top: 0; margin-top: 0; }
.meta-inline-summary {
  list-style: none; cursor: pointer;
  /* baseline so the small uppercase "Details" label and the larger italic
     summary text share a common baseline (bottom-aligned) rather than each
     centering by its own line box. */
  display: flex; align-items: baseline; gap: 12px;
  padding: 15px 2px; font-family: var(--font-sans);
}
.meta-inline-summary::-webkit-details-marker { display: none; }
.meta-inline-summary:hover .mi-label { color: var(--ink); }
.mi-label {
  font-size: 11px; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ink-muted); transition: color var(--dur-fast) ease;
}
.mi-meta {
  font-family: var(--font-serif); font-style: italic; font-size: 13.5px; color: var(--ink-faint);
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mi-chev { margin-left: auto; flex-shrink: 0; align-self: center; color: var(--ink-faint); transition: transform 200ms ease; }
.meta-inline[open] .mi-chev { transform: rotate(180deg); }
.meta-inline-body { padding: 2px 2px 22px; }

/* Wide: lift the metadata into a persistent left rail beside the article. */
@media (min-width: 1100px) {
  .layout:not(.layout--solo) {
    display: grid;
    grid-template-columns: 248px minmax(0, 720px);
    gap: 56px;
    justify-content: center;
    align-items: start;
  }
  .layout:not(.layout--solo) .doc { max-width: none; margin: 0; }
  .rail-col { display: block; position: relative; }
  /* Full-height hairline separating rail from article. */
  .rail-col::after {
    content: ""; position: absolute; top: 64px; bottom: 0; right: -28px; width: 1px;
    background: var(--paper-edge);
  }
  .rail-inner { padding: 64px 0 40px; }
  .rail-inner .section-label { margin-bottom: 14px; }
  .meta-inline { display: none; }
}

/* Item-detail page gives its <header class="head"> a full-bleed top band that
   sits directly beneath the global nav. Drop the article's top padding so the
   head provides the 56 px of breathing space instead (and so its full-bleed
   background can cover the full viewport width). The header scrolls away with
   the page — no sticky pin, no scroll-driven compaction. */
.doc--sticky { padding-top: 0; }

.doc--sticky .head {
  background: var(--paper);
  margin: 0 -32px;
  padding: 56px 32px 0;
}

/* ---------- Header ---------- */
.head .meta-row {
  font-family: var(--font-sans); font-size: 12px;
  color: var(--ink-faint);
  letter-spacing: 0.04em; text-transform: uppercase;
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 8px;
  flex-wrap: nowrap;
  min-width: 0;
}
.head .meta-row .meta-spacer { flex: 1; min-width: 16px; }
.head .meta-row .dot { width: 3px; height: 3px; border-radius: 50%; background: var(--ink-ghost); flex-shrink: 0; }
.head .meta-row .when {
  display: inline-flex; align-items: center; gap: 5px;
  color: var(--ink-muted);
  letter-spacing: 0.04em;
  white-space: nowrap;
  flex-shrink: 0;
}
.head .meta-row .when i { color: var(--ink-faint); }
.head .meta-row .timestamp {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.head .meta-row .ibtn { flex-shrink: 0; }

/* Secondary header rows — source URL, "Download original PDF". Each
   gets its own line below the meta row so a long URL doesn't push
   edit/delete onto a second line of the meta row. */
.head .head-link-row {
  font-family: var(--font-sans); font-size: 13px;
  margin: 0 0 6px;
  display: flex; align-items: center; gap: 6px;
  color: var(--ink-muted);
}
.head .head-link-row a {
  color: var(--ink-muted);
  text-decoration: none;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  display: inline-flex; align-items: center; gap: 6px;
  min-width: 0;
}
.head .head-link-row a:hover { color: var(--ink); }
.head .head-link-row i { color: var(--ink-faint); flex-shrink: 0; }
.head .head-link-row + h1 { margin-top: 18px; }

.head h1 {
  font-family: var(--font-serif); font-weight: 500;
  font-size: 38px; line-height: 1.18;
  letter-spacing: -0.01em;
  color: var(--ink-soft);
  margin: 0 0 10px;
  text-wrap: pretty;
}
.head .subhead {
  font-family: var(--font-serif); font-style: italic; font-weight: 400;
  font-size: 18px; line-height: 1.4;
  color: var(--ink-muted);
  margin: 0 0 28px;
}

/* Progressive-render placeholder: a calm line shown while a region (head /
   summary) is still being captured. No animation — the page fills in quietly. */
.capture-pending {
  font-family: var(--font-sans);
  font-size: 14px; line-height: 1.5;
  color: var(--ink-muted);
  margin: 0 0 28px;
}

/* ---------- Action bar: Read · stats · Mark Unread ---------- */
.actions-primary {
  display: flex; align-items: center; gap: 16px;
  margin-bottom: 32px;
  padding-bottom: 20px;
  border-bottom: 1px solid var(--paper-edge);
  flex-wrap: wrap;
  row-gap: 14px;
}
.actions-primary .actions-stats {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--font-sans); font-size: 13px;
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
  flex: 1;
  min-width: 0;
}
.actions-primary .actions-stats .dot {
  width: 3px; height: 3px; border-radius: 50%;
  background: var(--ink-ghost);
  flex-shrink: 0;
}
.actions-primary .actions-stats .pct {
  color: var(--ink); font-weight: 500;
}
/* Shelf toggles on the item page (spec 0071 § 2). Labelled rather than icon-only
   — the row has the width, and a bare bookmark glyph does not say which shelf it
   is. Pressed reads the same as it does in a list row: starred takes the one
   accent colour, want-to-read takes ink. Same treatment, different chassis. */
.actions-primary .shelf-toggle[aria-pressed="true"] {
  border-color: var(--ink-ghost);
  background: var(--paper-sunken);
}
.actions-primary .shelf-toggle[data-shelf="starred"][aria-pressed="true"] { color: #8a6d00; }
.actions-primary .shelf-toggle[data-shelf="starred"][aria-pressed="true"] svg {
  fill: rgba(255, 210, 0, 0.55);
}
.actions-primary .shelf-toggle[data-shelf="want_to_read"][aria-pressed="true"] { color: var(--ink); }
.actions-primary .shelf-toggle[disabled] { opacity: 0.55; cursor: default; }

.actions-primary form { margin: 0; padding: 0; display: inline; }
.actions-primary form button[type="submit"] {
  margin: 0;
  font-family: var(--font-sans); font-size: 13px; font-weight: 500;
  padding: 7px 12px; border-radius: var(--radius-sm);
  border: 1px solid var(--paper-edge); background: var(--paper-raised);
  color: var(--ink); cursor: pointer;
  display: inline-flex; align-items: center; gap: 7px;
  transition: background var(--dur-fast) ease;
}
.actions-primary form button[type="submit"]:hover { background: var(--paper-sunken); }

/* ---------- Banners (refining / outline) ---------- */
.banner {
  font-family: var(--font-sans); font-size: 13px;
  color: var(--ink-muted);
  background: var(--paper-sunken);
  border: 1px solid var(--paper-edge);
  border-radius: var(--radius-sm);
  padding: 10px 14px;
  margin: 0 0 24px;
}
.banner strong { color: var(--ink); font-weight: 600; }
.banner.warn { background: rgba(255, 210, 0, 0.10); border-color: rgba(255, 210, 0, 0.4); }

/* ---------- Note (marginalia, no header) ---------- */
.note-block {
  font-family: var(--font-serif);
  font-size: 17px; line-height: 1.55;
  color: var(--ink-soft);
  padding: 4px 0 4px 22px;
  border-left: 2px solid var(--ink-ghost);
  margin: 0 0 36px;
  position: relative;
}
/* Spec 0042: the note content is wrapped in an inner .prose (so it renders
   identically to the editor). Only zero the wrapper's outer margins here; all
   paragraph / heading / image styling comes from .prose, not .note-block. */
.note-block > :first-child { margin-top: 0; }
.note-block > :last-child { margin-bottom: 0; }
.note-block .prose > :last-child { margin-bottom: 0; }
.note-block .edit-affordance {
  position: absolute; right: -4px; top: -2px;
  font-family: var(--font-sans); font-size: 11px;
  color: var(--ink-faint); text-transform: uppercase; letter-spacing: 0.06em;
  padding: 4px 8px; border-radius: var(--radius-xs);
  text-decoration: none; opacity: 0;
  transition: opacity var(--dur-fast) ease;
}
.note-block:hover .edit-affordance { opacity: 1; color: var(--ink-muted); }

/* ---------- Highlights (no header — pulled passages) ---------- */
.highlights { margin: 0 0 44px; }
.highlight-passage {
  display: flex;
  align-items: center;
  gap: 18px;
  margin: 0 0 22px;
  padding: 4px 0 4px 22px;
  border-left: 2px solid var(--highlight);
}
.highlight-passage-main {
  flex: 1;
  min-width: 0;
  font-family: var(--font-serif);
  font-size: 19px; line-height: 1.55;
  color: var(--ink);
}
.highlight-passage:last-child { margin-bottom: 0; }
.highlight-passage .pg {
  display: block;
  font-family: var(--font-sans); font-size: 11px;
  color: var(--ink-faint);
  text-transform: uppercase; letter-spacing: 0.06em;
  margin-top: 8px;
  text-decoration: none;
}
.highlight-passage .pg:hover { color: var(--ink-muted); }

/* ---------- Divider ---------- */
.divider {
  border: 0;
  border-top: 1px solid var(--paper-edge);
  margin: 32px 0;
}

/* ---------- Summary (flowing serif) ---------- */
.summary {
  font-family: var(--font-serif);
  font-size: 19px; line-height: 1.65;
  color: var(--ink);
  margin-top: 12px;
}
.summary > :first-child { margin-top: 0; }
.summary p { margin: 0 0 1.05em; }
/* Drop cap on the summary's first letter — sets the summary apart from the
   framing block above it. Only when the summary opens with a paragraph
   (narrative summaries); outline/heading-led summaries are left alone.
   Uses `initial-letter` (3 lines tall, top-aligned to the first line) — the
   browser computes proper cap-height alignment, which the older float +
   line-height hack got wrong (the glyph rode too high). Browsers without
   support (e.g. Firefox) fall back to a plain bold first letter. */
.summary > p:first-child::first-letter {
  -webkit-initial-letter: 3;
  initial-letter: 3;
  font-family: var(--font-serif);
  font-weight: 600;
  margin-right: 0.09em;
  color: var(--ink);
}
.summary h1, .summary h2, .summary h3, .summary h4 {
  font-family: var(--font-serif); font-weight: 500;
  color: var(--ink-soft);
  line-height: var(--leading-snug);
  margin: 1.4em 0 0.5em;
}
.summary h1 { font-size: var(--text-2xl); }
.summary h2 { font-size: var(--text-xl); }
.summary h3 { font-size: var(--text-lg); }
.summary h4 { font-size: var(--text-md); }
.summary ul, .summary ol { padding-left: 1.5rem; margin: 0.75rem 0 1.05em; }
.summary ul { list-style: disc; }
.summary ol { list-style: decimal; }
.summary li { margin-bottom: 0.35rem; }
.summary li p { margin: 0; }
.summary a {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--ink-ghost);
  text-underline-offset: 3px;
}
.summary a:hover { text-decoration-color: var(--highlight); }
/* Summary images are wrapped by `resolve_image_tokens` in
   <a class="summary-img-link"> — the link is the card; the image
   fills it; PDF page caption sits below the image inside the same
   frame. */
.summary .summary-img-link {
  display: block;
  margin: 1.6em auto;
  width: 90%;
  background: var(--paper-raised);
  border: 1px solid var(--paper-edge);
  border-radius: var(--radius-image);
  padding: 6px;
  text-decoration: none;
  transition: border-color var(--dur-fast) ease;
}
.summary .summary-img-link:hover { border-color: var(--ink-ghost); }
.summary .summary-img-link img {
  display: block;
  width: 100%;
  height: auto;
  margin: 0;
  border: 0;
  padding: 0;
  background: transparent;
  border-radius: 0;
}
.summary .summary-img-page {
  display: block;
  font-family: var(--font-sans); font-size: 11px;
  color: var(--ink-faint);
  text-transform: uppercase; letter-spacing: 0.06em;
  margin-top: 8px;
  padding: 2px 4px 4px;
  font-variant-numeric: tabular-nums;
}
/* Multi-image paragraphs (comparison sets) lay side-by-side. */
.summary p:has(.summary-img-link + .summary-img-link) {
  display: flex; gap: 12px; flex-wrap: wrap; align-items: flex-start;
  justify-content: center;
}
.summary p:has(.summary-img-link + .summary-img-link) .summary-img-link {
  flex: 1 1 calc((100% - 12px) / 2);
  width: calc((100% - 12px) / 2);
  margin: 0;
}
/* Fallback: bare <img> in summary (no link wrapper). Keep the same
   card treatment so the layout is consistent. */
.summary > p > img:only-child,
.summary > img {
  display: block;
  margin: 1.6em auto;
  width: 90%;
  background: var(--paper-raised);
  border: 1px solid var(--paper-edge);
  border-radius: var(--radius-image);
  padding: 6px;
}
/* ---------- Image grid ---------- */
.grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 18px;
  margin: 0 0 48px;
}
@media (max-width: 640px) {
  .grid { grid-template-columns: 1fr; }
}
.grid a {
  display: block;
  background: var(--paper-raised);
  border: 1px solid var(--paper-edge);
  border-radius: var(--radius-image);
  padding: 6px;
  text-decoration: none;
  transition: border-color var(--dur-fast) ease;
}
.grid a:hover { border-color: var(--ink-ghost); }
.grid .frame {
  border: 1px solid var(--paper-edge);
  border-radius: var(--radius-image);
  overflow: hidden;
  background: var(--paper-sunken);
  aspect-ratio: 1 / 1;
  display: flex; align-items: stretch;
}
.grid .frame img {
  display: block; width: 100%; height: 100%;
  object-fit: contain;
}
.grid .pg {
  display: block;
  font-family: var(--font-sans); font-size: 10px;
  color: var(--ink-faint);
  letter-spacing: 0.06em;
  margin-top: 6px;
  padding: 0 2px 2px;
  font-variant-numeric: tabular-nums;
  text-transform: uppercase;
}

/* "See all" overflow tile — the 8th tile when the document has more
   than 8 eligible images. Visually mirrors the figure tiles but the
   frame holds a count and a label instead of a thumbnail. */
.grid a.more { background: var(--paper); }
.grid a.more .frame {
  background: var(--paper);
  border-style: dashed;
  border-color: var(--ink-ghost);
  align-items: center; justify-content: center;
  flex-direction: column;
  gap: 4px;
  padding: 8px;
  text-align: center;
}
.grid a.more:hover .frame {
  border-color: var(--ink-muted);
  background: var(--highlight-faint);
}
.grid a.more .more-n {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: 26px;
  color: var(--ink-soft);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.grid a.more .more-lbl {
  font-family: var(--font-sans);
  font-size: 10.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.grid a.more .pg { color: var(--ink-muted); }

/* ---------- Inline body (typed notes only) ---------- */
.body {
  font-family: var(--font-serif);
  font-size: 19px; line-height: 1.65;
  color: var(--ink);
  max-width: 68ch;
}
.body > :first-child { margin-top: 0; }
.body p { margin: 0 0 1.05em; }
.body h1, .body h2, .body h3, .body h4 {
  font-family: var(--font-serif); font-weight: 500;
  color: var(--ink-soft);
  line-height: var(--leading-snug);
  margin: 1.4em 0 0.5em;
}
.body h1 { font-size: var(--text-2xl); }
.body h2 { font-size: var(--text-xl); }
.body h3 { font-size: var(--text-lg); }
.body img {
  max-width: 100%;
  display: block;
  margin: 1.4em 0;
  border: 1px solid var(--paper-edge);
  border-radius: var(--radius-image);
  padding: 6px;
  background: var(--paper-raised);
}
.body ul, .body ol { padding-left: 1.5rem; margin: 0.75rem 0 1.05em; }
.body ul { list-style: disc; }
.body ol { list-style: decimal; }
.body a {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--ink-ghost);
  text-underline-offset: 3px;
}
.body a:hover { text-decoration-color: var(--highlight); }

/* ─── Spec 0009: related-items rail ───────────────────────────────────── */

.related-rail {
  margin: 2.5rem 0 0;
  display: flex;
  flex-direction: column;
  gap: 1.75rem;
}

.related-section {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.related-section__title {
  font-family: var(--font-sans);
  font-size: var(--text-lg);
  font-weight: 600;
  color: var(--ink);
  margin: 0;
}

.related-section--fallback .related-section__title {
  color: var(--ink-muted);
  font-size: var(--text-base);
  font-weight: 500;
}

.related-section__cards {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 0.75rem;
}

.related-card {
  padding: 0.75rem 0.9rem;
  border: 1px solid var(--paper-edge);
  border-radius: var(--radius-image, 6px);
  background: var(--paper-raised);
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.related-section--fallback .related-card {
  background: var(--paper-sunken);
  border-color: var(--paper-edge);
}

.related-card__title {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--text-base);
  font-weight: 500;
  color: var(--ink);
}

.related-card__brief {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--ink-muted);
  line-height: var(--leading-snug, 1.35);
}

.related-card__link {
  text-decoration: none;
  color: inherit;
}
.related-card__link:hover .related-card__title {
  text-decoration: underline;
  text-decoration-color: var(--ink-ghost);
}

.related-card__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  align-items: center;
}

.related-card__chip {
  font-size: var(--text-xs);
}

.related-card__chip--edge-contradicts,
.related-card__chip--edge-qualifies {
  border-color: var(--ink-warn, var(--ink-muted));
  color: var(--ink-warn, var(--ink-muted));
}

.related-card__chip--edge-supports,
.related-card__chip--edge-parallels {
  border-color: var(--ink-soft);
  color: var(--ink-soft);
}

.related-card__chip--edge-extends,
.related-card__chip--edge-refines {
  border-color: var(--ink);
  color: var(--ink);
}

.related-card__match-count {
  font-size: var(--text-xs);
  color: var(--ink-muted);
}

.related-card--image .related-card__image-pair {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.25rem;
}

.related-card--image .related-card__image-pair img {
  max-width: 120px;
  max-height: 90px;
  border: 1px solid var(--paper-edge);
  border-radius: 4px;
  object-fit: cover;
  margin: 0;
  padding: 0;
  background: var(--paper);
}

.related-card__image-pair-sep {
  color: var(--ink-muted);
  font-size: var(--text-lg);
}

.related-section__more {
  font-size: var(--text-sm);
  color: var(--ink-soft);
  text-decoration: none;
  margin-top: 0.25rem;
  align-self: flex-start;
}
.related-section__more:hover { text-decoration: underline; }

.related-all-results__header { margin-bottom: 1.5rem; }
.related-all-results__back {
  font-size: var(--text-sm);
  color: var(--ink-muted);
  text-decoration: none;
}
.related-all-results__back:hover { text-decoration: underline; }
.related-all-results__title {
  margin: 0.4rem 0 0;
  font-family: var(--font-serif);
  font-size: var(--text-xl);
  font-weight: 500;
}
.related-all-results__list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 0.75rem;
}
.related-all-results__subtitle {
  margin: 0.25rem 0 0;
  font-family: var(--font-sans);
  font-size: 12px;
  color: var(--ink-faint);
  letter-spacing: 0.02em;
}

/* =================================================================
   Related-items rail v2 (design bundle: saved-page.html)
   - section-label: heading + inline lbl-method slug + trailing rule
   - .relation-card: semantic relations (Deepens/Widens/Tension/Reframes/Bridges)
   - .similar-card / .similar-row: ANN/fallback ranked rows (Similar items/images)
   ================================================================= */

.related-rail .related-section { margin: 0 0 56px; }
.related-rail .related-section + .related-section { margin-top: -8px; }

.section-label {
  font-family: var(--font-sans); font-size: 11px; font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ink-muted);
  margin: 0 0 18px;
  display: flex; align-items: center; gap: 12px;
}
.section-label::after {
  content: ""; flex: 1; height: 1px; background: var(--paper-edge);
}
.section-label .lbl-method {
  font-weight: 400;
  letter-spacing: 0.04em;
  text-transform: none;
  color: var(--ink-faint);
  font-size: 12px;
}

/* ─── Semantic relation card ─────────────────────────────────────── */
/* Spec 0062 — the rail's relationship + similar cards now reuse the /related page's
   shared `.rel-all-card` / `.related-all__similar` styling (see _relation_card.html /
   _similar_row.html) for cross-surface consistency; the legacy `.relation-card` /
   `.rel-chip` / `.similar-card` rail styles below are no longer emitted. */
.relation-card {
  background: var(--paper-raised);
  border: 1px solid var(--paper-edge);
  border-radius: 8px;
  padding: 18px 20px 18px;
}
.relation-card + .relation-card { margin-top: 12px; }

/* Admin-only debug instrumentation badge — gated by request.user.is_staff
   in templates. Used to surface internal numbers (cohesion scores etc.)
   without leaking them into end-user UI. */
.dev-badge {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--ink-faint);
  margin-left: 6px;
  vertical-align: baseline;
  letter-spacing: 0.02em;
}

/* Chip row: ≤ 3 chips per card, family-collapsed when the card
   surfaces from more dimensions than fit. First chip aligns with
   the prose; the rest are by rank. */
.rel-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 6px;
  margin: 0 0 10px -6px;
}

/* The signature element: a serif rel-chip highlighted in the same
   yellow as a marker pulled across the page. */
.rel-chip {
  display: inline-block;
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 14.5px;
  line-height: 1.35;
  color: var(--ink);
  background: var(--highlight-wash);
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
  padding: 2px 6px;
  border-radius: 2px;
}
/* Inside a .rel-chips row the margin moves to gap, so reset the
   solo-chip margin. Solo `.rel-chip` (legacy) keeps its own spacing. */
.rel-chips > .rel-chip { margin: 0; }

.rel-head {
  display: flex; align-items: center; gap: 10px;
  min-width: 0;
  margin: 0 0 4px;
}
.rel-title {
  font-family: var(--font-sans); font-weight: 500;
  font-size: 16px; line-height: 1.3;
  color: var(--ink-soft);
  text-decoration: none;
  letter-spacing: -0.005em;
  min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.rel-title:hover { color: var(--ink); }
.rel-title:hover .title-text {
  box-shadow: inset 0 -0.4em 0 var(--highlight-wash);
}

/* Type chip next to the title — mirrors .kind on the page header. */
.rel-kind {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--font-sans); font-size: 11px; font-weight: 500;
  text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--ink-muted);
  padding: 2px 8px; border-radius: 4px;
  background: var(--paper-sunken);
  flex-shrink: 0;
}
.rel-kind.book    { color: #4a4a4a; background: #ececec; }
.rel-kind.pdf     { color: #5a4634; background: #efe9df; }
.rel-kind.webpage { color: #4a4a4a; background: #ececec; }
.rel-kind.note    { color: #6a4f0f; background: rgba(255, 210, 0, 0.18); }

.rel-explain {
  font-family: var(--font-serif);
  font-size: 16px; line-height: 1.5;
  color: var(--ink-soft);
  max-width: 68ch;
  margin: 0;
}
.rel-explain em { font-style: italic; color: var(--ink); }

.related-card__see-all-reasons {
  display: inline-block;
  margin-top: 10px;
  font-family: var(--font-sans); font-size: 12px;
  color: var(--ink-muted);
  text-decoration: none;
  border-bottom: 1px solid var(--paper-edge);
  padding-bottom: 1px;
}
.related-card__see-all-reasons:hover { color: var(--ink); border-bottom-color: var(--ink-ghost); }

/* The Explain button — the "deep on demand" affordance, an outline button in the
 * design-system idiom (paper-raised, paper-edge). SHARED by the /explore discovery
 * panels (spec 0060) and the item-page related rail / See-all (spec 0062) — moved
 * here from agent.css so both surfaces reuse ONE rule (main.css loads globally).
 * Scoped under `.explain-form` (0,2,0) so it beats the global
 * `form button[type="submit"]` (0,1,2) primary rule — otherwise it renders as a
 * dark primary. Hover is the quiet GRAY wash, NOT the yellow highlight. */
.explain-form {
  margin: 0;
  flex: none;
}
.explain-form .explain-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 0;  /* reset the global form-submit margin */
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 500;
  color: var(--ink);
  background: var(--paper-raised);
  border: 1px solid var(--paper-edge);
  border-radius: 6px;
  padding: 7px 14px;
  cursor: pointer;
  transition: background var(--dur-fast) ease, border-color var(--dur-fast) ease;
}
.explain-form .explain-btn:hover {
  background: var(--paper-sunken);
  border-color: var(--ink-faint);
  color: var(--ink);
}
/* The rail button adds a sparkle (the /explore buttons have none); it inherits the
   ink text (stroke="currentColor") so it reads on the light fill. */
.explain-form .explain-btn svg { color: var(--ink); }

/* ── Spec 0035 — "How this fits" (item_fit) ─────────────────────────────────
 * The persisted item-page agent framing. Imported from the design's `.fits`
 * component; tokens are the shared design.css set. Three states (empty prompt /
 * written body + provenance foot / stale note + body) + a generating shimmer. */
/* Sits between the summary and the related rail; mirrors the rail's top rhythm
 * (.related-rail margin-top 2.5rem) so summary → fits → first edge is even. */
.item-fit-region { margin: 2.5rem 0 0; }
.fits {
  background: var(--paper-raised);
  border: 1px solid var(--paper-edge);
  border-radius: 8px;
  padding: 22px 24px;
}
.fits-prompt { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
.fits-prompt p {
  flex: 1; min-width: 240px; margin: 0;
  font-family: var(--font-serif); font-style: italic;
  font-size: 16.5px; line-height: 1.5; color: var(--ink-muted);
}
.fits-body {
  font-family: var(--font-serif); font-size: 18px; line-height: 1.6; color: var(--ink);
}
.fits-body p { margin: 0 0 0.8em; text-wrap: pretty; }
.fits-body p:last-child { margin: 0; }
.fits-body a {
  color: inherit; text-decoration: none;
  box-shadow: inset 0 -1px 0 var(--ink-ghost);
}
.fits-body a:hover { box-shadow: inset 0 -0.4em 0 var(--highlight-wash); }
.fits-foot {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 18px; padding-top: 14px;
  border-top: 1px solid var(--paper-edge);
  font-family: var(--font-sans); font-size: 12px; color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}
.fits-foot .dot { width: 3px; height: 3px; border-radius: 50%; background: var(--ink-ghost); }
.fits-stale-note {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin: 0 0 18px; padding: 11px 14px;
  background: var(--highlight-faint);
  border: 1px solid rgba(202, 168, 58, 0.3);
  border-radius: 6px;
}
.fits-stale-note p {
  flex: 1; min-width: 200px; margin: 0;
  font-family: var(--font-sans); font-size: 13px; line-height: 1.45; color: var(--ink-soft);
}
.fits-stale-note p b { font-weight: 600; }
.fits-stale-note .warn { color: #8a6a1f; flex: none; font-size: 15px; }
.fits[data-fits="stale"] .fits-body { color: var(--ink-soft); }
/* Skeleton shimmer shown between clicking "How this fits" and the first streamed
 * token, so the box is never blank-white. Animated placeholder bars (a sliding
 * gradient) that fill the box's prose height. */
.fits-shimmer { display: flex; flex-direction: column; gap: 14px; padding: 2px 0; }
.fits-shimmer__line {
  height: 15px;
  border-radius: 4px;
  background: linear-gradient(
    90deg,
    var(--paper-sunken) 25%,
    var(--paper-edge) 50%,
    var(--paper-sunken) 75%
  );
  background-size: 200% 100%;
  animation: fits-shimmer-slide 1.4s ease-in-out infinite;
}
.fits-shimmer__line--short { width: 55%; }
@keyframes fits-shimmer-slide {
  from { background-position: 200% 0; }
  to { background-position: -200% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .fits-shimmer__line { animation: fits-pulse 1.6s ease-in-out infinite; }
}
@keyframes fits-pulse { 0%, 100% { opacity: 0.5; } 50% { opacity: 0.85; } }
.fits-busy {
  margin: 12px 0 0; font-family: var(--font-sans); font-size: 12.5px; color: var(--ink-muted);
}

/* ── Spec 0047 — per-item "questions to ask" ────────────────────────────────
 * The card itself is now `design.css`'s shared `.q-list` (spec 0073 made the
 * collection page's treatment the default for every question surface). Only the
 * section's own spacing lives here. The `.q-card` family this replaced —
 * including `.q-pending`/`.q-shimmer-line`, unused since #274 made the pending
 * state an invisible poller — is gone with it. */
.item-questions-region { margin: 2.5rem 0 0; }

/* ── Spec 0047 PR4 — home-deck "Questions to ask" pool card ──────────────────
 * Imported from Home.html. One item per page: title + kind + summary + ≤3 rows.
 * Scoped under `.card .item-questions` so it (a) beats the global
 * `form button[type="submit"]` primary rule and (b) doesn't collide with the
 * item-page `.q-card` sizing. */
.item-questions .q-head {
  display: flex; align-items: baseline; gap: 8px; min-width: 0; margin: 0 0 5px;
}
.item-questions .q-item {
  font-family: var(--font-serif); font-weight: 500;
  font-size: 20px; line-height: 1.2; letter-spacing: -0.01em;
  color: var(--ink-soft); margin: 0; min-width: 0;
  text-decoration: none;
}
.item-questions .q-item:hover { color: var(--ink); }
.item-questions .q-head .kind { align-self: center; }
.item-questions .q-summary {
  font-family: var(--font-sans); font-size: 12.5px; line-height: 1.5;
  color: var(--ink-muted); margin: 0 0 12px;
}
.item-questions .q-row-form { margin: 0; }
.card .item-questions .q-row {
  display: block; width: 100%; text-align: left;
  margin: 0; padding: 10px 8px 11px;
  border: 0; border-radius: 6px;
  background: transparent; cursor: pointer; text-decoration: none;
}
.card .item-questions .q-row-form:not(:last-child) .q-row {
  box-shadow: 0 1px 0 var(--paper-edge);
}
.card .item-questions .q-row:hover { background: var(--highlight-faint); box-shadow: none; }
.item-questions .q-row .q-text {
  font-family: var(--font-serif); font-size: 15px; line-height: 1.45; font-weight: 400;
  color: var(--ink-soft); margin: 0; text-wrap: pretty;
}
.card .item-questions .q-row:hover .q-text { color: var(--ink); }

/* Similar (fallback) rows: the row's body anchor opens the item. */
.similar-row__open {
  display: grid;
  grid-template-columns: 28px 1fr;
  gap: 14px;
  align-items: start;
  text-decoration: none;
  color: inherit;
  flex: 1;
}
.similar-row__open:hover { background: var(--highlight-faint); }

/* ─── Similar (ANN / fallback) ranked rows ───────────────────────── */
.similar-card {
  background: var(--paper-raised);
  border: 1px solid var(--paper-edge);
  border-radius: 8px;
  padding: 4px 8px;
}
/* The row is a 28px|1fr grid; the body is the 1fr child. Grid items default
 * to min-width:auto, so the nowrap title (below) would refuse to shrink and
 * overflow the card off the right edge on narrow screens. min-width:0 lets
 * the track shrink so the title ellipsis-truncates instead. */
.similar-card .body { min-width: 0; }
.similar-row {
  display: grid;
  grid-template-columns: 28px 1fr;
  gap: 14px;
  padding: 14px 12px;
  border-bottom: 1px solid var(--paper-edge);
  align-items: start;
  text-decoration: none;
  color: inherit;
  border-radius: 6px;
}
.similar-row:last-child { border-bottom: 0; }
.similar-row:hover { background: var(--highlight-faint); border-bottom-color: transparent; }
.similar-row .rank {
  font-family: var(--font-sans); font-size: 12px; font-weight: 600;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
  padding-top: 2px;
}
.similar-row .body .row-head {
  display: flex; align-items: center; gap: 10px;
  min-width: 0;
  margin: 0 0 3px;
}
.similar-row .body .title {
  font-family: var(--font-sans); font-weight: 500; font-size: 15px;
  color: var(--ink-soft);
  line-height: 1.3;
  margin: 0;
  letter-spacing: -0.005em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.similar-row .body .why {
  font-family: var(--font-sans); font-size: 12.5px;
  color: var(--ink-muted);
  line-height: 1.45;
  margin: 0;
}
.similar-row .meta {
  font-family: var(--font-sans); font-size: 11px;
  color: var(--ink-faint);
  letter-spacing: 0.06em; text-transform: uppercase;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  padding-top: 4px;
}

/* ─── Similar Images cards ─────────────────────────────────────────────────
   Visual-neighbour section in the rail. Per the design bundle
   (memex-design-system/saved-page.html § "Similar images"), the figures
   carry the meaning here — title + reason become compact metadata, and
   the actual images sit large, side-by-side, in hairline frames. The
   seed item's image is on the left ("This <Type>"); the related item's
   matching image is on the right (target title). A small arrow chip
   pairs them ("this looks like that"). */
.simimg-card {
  background: var(--paper-raised);
  border: 1px solid var(--paper-edge);
  border-radius: 8px;
  padding: 18px 22px 22px;
  display: block;
  text-decoration: none;
  color: inherit;
  transition: background var(--dur-fast, 120ms) ease;
}
.simimg-card + .simimg-card { margin-top: 10px; }
.simimg-card:hover { background: var(--highlight-faint); }
.simimg-head {
  display: grid;
  grid-template-columns: 28px 1fr;
  gap: 14px;
  align-items: baseline;
}
.simimg-head .rank {
  font-family: var(--font-sans); font-size: 12px; font-weight: 600;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}
.simimg-head .row-head {
  display: flex; align-items: center; gap: 10px;
  min-width: 0;
}
.simimg-head .title {
  font-family: var(--font-sans); font-weight: 500; font-size: 15px;
  color: var(--ink-soft);
  line-height: 1.3;
  margin: 0;
  letter-spacing: -0.005em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.simimg-why {
  font-family: var(--font-sans); font-size: 12.5px;
  color: var(--ink-muted);
  line-height: 1.5;
  margin: 4px 0 18px 42px;
  max-width: 62ch;
}
.simimg-pair {
  display: grid;
  grid-template-columns: 1fr 32px 1fr;
  gap: 18px;
  align-items: stretch;
  margin-left: 42px;
}
.simimg-figure { min-width: 0; display: flex; flex-direction: column; }
.simimg-frame {
  height: 200px;
  background: #ffffff;
  border: 1px solid var(--paper-edge);
  border-radius: 8px;
  overflow: hidden;
  display: grid;
  place-items: center;
  padding: 16px;
}
.simimg-frame img, .simimg-frame svg {
  width: 100%; height: 100%;
  object-fit: contain;
  display: block;
}
.simimg-caption {
  margin: 10px 2px 0;
  font-family: var(--font-sans); font-size: 11px;
  color: var(--ink-faint);
  display: flex; flex-direction: column; gap: 2px;
  line-height: 1.35;
  min-width: 0;
}
.simimg-caption .src-tag {
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-muted);
  letter-spacing: -0.005em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.simimg-figure.is-this .simimg-caption .src-tag { color: var(--ink-soft); }
.simimg-link {
  align-self: center;
  width: 32px; height: 32px;
  border-radius: 50%;
  background: var(--paper);
  border: 1px solid var(--paper-edge);
  display: grid; place-items: center;
  color: var(--ink-faint);
}
.simimg-card:hover .simimg-link {
  color: var(--ink-muted);
  border-color: var(--ink-ghost);
}
@media (max-width: 720px) {
  .simimg-why { margin-left: 0; }
  .simimg-pair {
    grid-template-columns: 1fr;
    margin-left: 0;
    gap: 14px;
  }
  .simimg-link {
    justify-self: center;
    transform: rotate(90deg);
  }
  .simimg-frame { height: 180px; }
}

/* "See all →" link below a section in the rail. */
.related-rail .related-section__more {
  margin-top: 16px;
  font-family: var(--font-sans); font-size: 13px;
}
.related-rail .related-section__more a {
  color: var(--ink-muted);
  text-decoration: none;
  border-bottom: 1px solid var(--paper-edge);
  padding-bottom: 1px;
  display: inline-flex; align-items: center; gap: 6px;
}
.related-rail .related-section__more a:hover {
  color: var(--ink); border-bottom-color: var(--ink-ghost);
}

/* ---------- Spec 0022 — framing prose (Locate + Reconcile) ---------- */
.framing { margin: 0.25rem 0 1.75rem; }
.framing-locate.prose { margin-bottom: 0.5rem; }
.framing-refining { font-size: 13px; color: var(--ink-muted); }
.framing-reconcile { margin: 0.75rem 0; }
.framing-reconcile summary {
  cursor: pointer; font-family: var(--font-sans); font-size: 13px;
  color: var(--ink-soft); margin-bottom: 0.25rem;
}
.framing-actions { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin-top: 0.6rem; }
.framing-feedback { display: inline-flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; margin-top: 0.6rem; }
.framing-feedback-label { font-size: 12px; }
/* Compact flag/dismiss buttons — meta-actions, lighter than a full .btn. */
.framing-actions .btn, .framing-feedback .btn { font-size: 12px; padding: 4px 9px; }
.framing-actions form { margin: 0; }

/* ── Spec 0049 — inline selection-explain ─────────────────────────────────── */
/* The "Explain" button stands on its own (no sibling "Highlight"), so it carries a
   full border to read as a real button — matching the reader-popover treatment.
   Shared look for the per-highlight button and the floating selection trigger. */
.explain-inline-btn,
.explain-trigger {
  flex: none;
  font-family: var(--font-sans); font-size: 13px; font-weight: 600;
  color: var(--ink); background: var(--paper-raised);
  border: 1px solid var(--paper-edge); border-radius: var(--radius-sm);
  padding: 6px 14px; cursor: pointer;
}
.explain-inline-btn:hover,
.explain-trigger:hover { background: var(--paper-sunken); }

/* The floating trigger additionally lifts off the text it hovers over. */
.explain-trigger {
  position: absolute; z-index: 40;
  box-shadow: 0 6px 18px rgba(40, 34, 26, 0.14);
}

/* The inline explanation panel — fixed, right-anchored, self-contained. */
.explain-panel {
  position: fixed; z-index: 60; top: 84px; right: 24px;
  width: min(420px, calc(100vw - 48px)); max-height: calc(100vh - 120px);
  overflow-y: auto;
  background: var(--paper-raised);
  border: 1px solid var(--paper-edge); border-radius: var(--radius-md, 10px);
  box-shadow: 0 18px 44px rgba(40, 34, 26, 0.18);
  padding: 20px 22px 22px;
}
.explain-panel-close {
  position: absolute; top: 8px; right: 12px;
  font-size: 22px; line-height: 1; color: var(--ink-muted);
  background: transparent; border: none; cursor: pointer;
}
.explain-panel-close:hover { color: var(--ink); }
.explain-panel-loading { font-family: var(--font-sans); font-size: 14px; color: var(--ink-muted); }

/* The card itself (shared with the reader popover + status poll). */
.explain-card-heading {
  font-family: var(--font-sans); font-size: 13px; font-weight: 600;
  color: var(--ink-muted); text-transform: none; letter-spacing: 0;
  margin: 0 0 12px;
}
.explain-card-body { font-family: var(--font-serif); color: var(--ink-soft); }
.explain-card-body h2 {
  font-family: var(--font-sans); font-size: 12px; font-weight: 600;
  color: var(--ink-muted); text-transform: uppercase; letter-spacing: 0.04em;
  margin: 16px 0 6px;
}
.explain-card-further {
  display: inline-block; margin-top: 16px;
  font-family: var(--font-sans); font-size: 13px; font-weight: 600;
  color: var(--ink); text-decoration: none;
  border-bottom: 1px solid var(--highlight); padding-bottom: 1px;
}
.explain-card-further:hover { border-bottom-color: var(--ink); }
.explain-card-error { font-family: var(--font-sans); font-size: 14px; color: var(--danger); }

/* ============================================================
   Spec 0062 — /items/<uuid>/related/ consolidated "all relationships"
   page (design: Related.dc.html). A sticky header with scroll-spy tabs
   over anchored sections of relationship cards + a Similar-items list.
   ============================================================ */
.related-all {
  max-width: 900px;
  margin: 0 auto;
  padding: 0 32px 160px;
  font-family: var(--font-sans);
  color: var(--ink);
}
.related-all__header {
  position: sticky;
  top: 57px;
  z-index: 18;
  background: var(--paper);
  margin: 0 -32px;
  padding: 34px 32px 0;
}
.related-all__back {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 13px;
  color: var(--ink-muted);
  text-decoration: none;
  margin-bottom: 18px;
}
.related-all__back svg { color: var(--ink-faint); }
.related-all__back:hover { color: var(--ink); }
.related-all__title {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: 38px;
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: var(--ink-soft);
  margin: 0 0 12px;
  text-wrap: pretty;
}
.related-all__title a {
  font-style: italic;
  color: inherit;
  text-decoration: none;
  border-radius: 2px;
  padding: 0 2px;
  margin: 0 -2px;
}
.related-all__title a:hover { background: var(--highlight-wash); }
.related-all__meta {
  font-size: 13px;
  color: var(--ink-muted);
  margin: 0 0 24px;
  font-variant-numeric: tabular-nums;
}
.related-all__tabs {
  display: flex;
  gap: 26px;
  margin: 0 -32px;
  padding: 0 32px;
  border-bottom: 1px solid var(--paper-edge);
  overflow-x: auto;
}
.related-all__tab {
  font-size: 14px;
  font-weight: 500;
  text-decoration: none;
  padding: 10px 0 13px;
  margin-bottom: -1px;
  white-space: nowrap;
  border-bottom: 2px solid transparent;
  color: var(--ink-muted);
}
.related-all__tab:hover { color: var(--ink); }
.related-all__tab.is-active {
  color: var(--ink);
  border-bottom-color: var(--highlight);
}
.related-all__tab-count {
  font-size: 12px;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}

/* Sections + their headers */
.related-all__section { padding-top: 48px; }
.related-all__section:first-of-type { padding-top: 40px; }
.related-all__section-head {
  display: flex;
  align-items: baseline;
  gap: 14px;
  margin-bottom: 18px;
}
.related-all__section-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0;
  white-space: nowrap;
}
.related-all__section-sub { font-size: 13px; color: var(--ink-muted); }
.related-all__rule { flex: 1; height: 1px; background: var(--paper-edge); }

/* Shared: item title + kind badge row */
.related-all__head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 6px;
}
.related-all__kind {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-muted);
  background: var(--paper-sunken);
  border-radius: 4px;
  padding: 3px 7px;
  white-space: nowrap;
}

/* Relationship cards (Deepens / Widens / Bridges) */
.related-all__cards { display: flex; flex-direction: column; gap: 16px; }
.rel-all-card {
  background: var(--paper-raised);
  border: 1px solid var(--paper-edge);
  border-radius: 8px;
  padding: 22px 24px;
}
.rel-all-card__reasons {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 16px;
}
.rel-all-reason {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-soft);
  background: var(--highlight-faint);
  border-radius: 4px;
  padding: 4px 8px;
}
.rel-all-card__row { display: flex; align-items: flex-start; gap: 24px; }
.rel-all-card__body { flex: 1; min-width: 0; }
.rel-all-card__title {
  font-family: var(--font-serif);
  font-size: 21px;
  font-weight: 500;
  line-height: 1.25;
  color: var(--ink-soft);
  text-decoration: none;
  border-radius: 2px;
  padding: 0 2px;
  margin: 0 -2px;
  text-wrap: pretty;
}
.rel-all-card__title:hover { background: var(--highlight-wash); }
.rel-all-card__desc {
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--ink-muted);
  margin: 0;
  text-wrap: pretty;
}

/* Similar items — a compact ranked list in one container */
.related-all__similar {
  background: var(--paper-raised);
  border: 1px solid var(--paper-edge);
  border-radius: 8px;
  padding: 4px 8px;
}
.related-all__similar-row {
  display: grid;
  grid-template-columns: 34px 1fr;
  gap: 14px;
  padding: 16px 14px;
  text-decoration: none;
  color: inherit;
  border-radius: 6px;
}
.related-all__similar-row + .related-all__similar-row { border-top: 1px solid var(--paper-edge); }
.related-all__similar-row:hover { background: var(--highlight-faint); }
.related-all__rank {
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
  padding-top: 5px;
}
.related-all__similar-body { min-width: 0; }
.related-all__similar-title {
  font-family: var(--font-serif);
  font-size: 18px;
  font-weight: 500;
  line-height: 1.25;
  color: var(--ink-soft);
}
.related-all__why {
  font-size: 13px;
  line-height: 1.45;
  color: var(--ink-muted);
  margin: 0;
  text-wrap: pretty;
}
.related-all__note { font-size: 12px; color: var(--ink-faint); margin: 14px 4px 0; }
.related-all__simimg { display: flex; flex-direction: column; gap: 14px; }
.related-all__empty { color: var(--ink-muted); padding: 60px 0; }

@media (max-width: 640px) {
  .related-all { padding: 0 18px 120px; }
  .related-all__header { margin: 0 -18px; padding: 24px 18px 0; }
  .related-all__tabs { margin: 0 -18px; padding: 0 18px; }
  .related-all__title { font-size: 30px; }
}

/* ---------- Canonical item row: state, membership, selection (spec 0070 § 4) ----------
   These extend the `.item` row above rather than replacing it — `.title` (sans)
   and `.summary` (serif) are already correct, and the row partial reuses them.
   Global on purpose: one row renders /items, the home deck, collection pages,
   agent results and the framing pages, so its pieces cannot live in items.css. */

/* Shelf toggles. Pressed states are the only colour on the row, and they use
   the one accent — a starred item gets the highlighter yellow it would get if
   you had drawn on it.

   Keyed on `.row-actions`, not on `.item`: there are two row shapes — `.item`
   and the lens pages' `.result` (spec 0078) — and a starred item has to look
   starred on both. Scoped to `.item` these silently did not reach the framing
   row, which rendered `aria-pressed="true"` and drew an unfilled outline, so
   the state was correct and unreadable. */
.row-actions .ibtn.star[aria-pressed="true"] { color: #8a6d00; }
.row-actions .ibtn.star[aria-pressed="true"] svg { fill: rgba(255, 210, 0, 0.55); }
.row-actions .ibtn.want[aria-pressed="true"] { color: var(--ink); }
.row-actions .ibtn.want[aria-pressed="true"] svg { fill: var(--ink-ghost); }

/* The row's overflow menu (spec 0075 § 2). Rare, permanent, or leaves-the-app
   actions live behind it so the three everyday toggles stay one click and Delete
   takes two — the design's own division, ported from `preview/item-card.html`.
   Floating UI, so the shadow is allowed here (design rule 6). */
.ovf { position: relative; display: inline-flex; }
.ovf-menu {
  position: absolute; top: calc(100% + 6px); right: 0;
  min-width: 190px;
  background: var(--paper-raised);
  border: 1px solid var(--paper-edge);
  border-radius: var(--radius-md);
  box-shadow: 0 8px 24px rgba(28, 26, 23, 0.12);
  padding: 5px;
  z-index: 30;
  display: flex; flex-direction: column; gap: 1px;
}
.ovf-menu[hidden] { display: none; }
.ovf-item {
  display: flex; align-items: center; gap: 9px;
  width: 100%;
  padding: 8px 10px;
  border: 0; border-radius: 5px;
  background: none;
  font-family: var(--font-sans); font-size: 13px;
  color: var(--ink-soft);
  text-align: left; cursor: pointer; text-decoration: none;
}
.ovf-item:hover { background: var(--paper-sunken); }
.ovf-item.danger { color: var(--danger); }
.ovf-item.danger:hover { background: rgba(138, 47, 42, 0.06); }

/* Collection membership. A bordered pill means CONTAINMENT — a finite place you
   can go. Plain inline text means aboutness (concepts, inferred and ranked).
   Keeping those two apart on every surface is what makes either legible. */
.item .meta-row.collections { margin-top: 2px; }
/* `.meta-row` is `display: flex`, which would defeat the attribute on its own.
 * The row ships this container even when the item is in no collection, so that
 * filing from a bulk picker appends a pill instead of building the block. */
.item .meta-row.collections[hidden] { display: none; }
.coll-lead { font-family: var(--font-sans); font-size: 11.5px; color: var(--ink-faint); }
.coll-pill {
  display: inline-flex; align-items: center;
  padding: 2px 8px;
  border-radius: var(--radius-xs);
  border: 1px solid var(--paper-edge);
  background: var(--paper-sunken);
  font-family: var(--font-sans); font-size: 11.5px;
  color: var(--ink-muted);
  text-decoration: none;
}
.coll-pill:hover { color: var(--ink); border-color: var(--ink-ghost); }

/* Selection checkbox. It sits in the page gutter rather than in the grid so
   that entering bulk mode never shifts the rows sideways — the reader keeps
   their place. Surfaces that adopt `select` need that gutter to exist. */
.item.is-selectable { position: relative; }
.item .pick {
  position: absolute; left: -22px; top: 22px;
  width: 18px; height: 18px;
  border-radius: var(--radius-xs);
  border: 1px solid var(--ink-ghost);
  background: var(--paper-raised);
  display: none; place-items: center;
  color: transparent;
  cursor: pointer; padding: 0;
}
/* A DESCENDANT rule, not `.items.picking`. The `picking` class lands on the
   select SCOPE, and the scope is not always the row container: on /items and a
   collection page the scope IS the `.items` section, but an agent answer wraps
   several `.group > .items` in one scope (0076). Keyed on `.items` it matched
   the first two and silently missed the third — the group box appeared and the
   row boxes did not. */
.picking .item .pick { display: grid; }
.item.is-picked .pick { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.item.is-picked { background: var(--paper-sunken); }

/* ---------- The toolbar sort dropdown ----------
   Global for the same reason the row is: /items, the collections index and
   a collection's member list all render it from `_sort_menu.html`. It lived
   in items.css while /items was the only caller. */
.sort { position: relative; flex: none; }
.sort-btn {
  font-family: var(--font-sans); font-size: 13px; font-weight: 500;
  padding: 7px 11px; border-radius: 6px;
  border: 1px solid var(--paper-edge); background: var(--paper-raised);
  color: var(--ink); cursor: pointer;
  display: inline-flex; align-items: center; gap: 7px;
  white-space: nowrap;
  transition: background 120ms ease;
}
.sort-btn:hover { background: var(--paper-sunken); }
.sort-btn .lead { color: var(--ink-faint); }
.sort-btn .sort-cur { color: var(--ink-soft); }
.sort-btn .caret { color: var(--ink-faint); transition: transform 140ms ease; }
.sort-btn[aria-expanded="true"] .caret { transform: rotate(180deg); }

.sort-menu {
  position: absolute; right: 0; top: calc(100% + 6px);
  z-index: 30;
  background: var(--paper-raised);
  border: 1px solid var(--paper-edge);
  border-radius: 8px;
  box-shadow: 0 10px 30px rgba(26,26,26,0.10), 0 2px 6px rgba(26,26,26,0.05);
  padding: 5px;
  min-width: 196px;
}
.sort-menu[hidden] { display: none; }

.sort-opt {
  display: flex; align-items: center; gap: 8px; width: 100%;
  font-family: var(--font-sans); font-size: 13px; font-weight: 500;
  color: var(--ink-soft);
  text-decoration: none;
  padding: 8px 9px; border-radius: 6px; text-align: left;
}
.sort-opt:hover { background: var(--paper-sunken); }
.sort-opt .sub { color: var(--ink-faint); font-weight: 400; font-size: 11.5px; }
.sort-opt .tick { margin-left: auto; display: inline-flex; color: var(--ink); opacity: 0; }
.sort-opt[aria-checked="true"] .tick { opacity: 1; }

/* ---------- The `select` bulk pattern (spec 0070 § 5) ----------
   Shared by /items, collection pages and agent results. Floating UI, so it is
   one of the few places a shadow is allowed (design rule 6). */
.select-link {
  font-family: var(--font-sans); font-size: 13px; font-weight: 500;
  color: var(--ink-muted); text-decoration: none;
  padding: 7px 4px;
  display: inline-flex; align-items: center; gap: 6px;
  cursor: pointer; white-space: nowrap;
  background: none; border: 0;
}
.select-link:hover { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
.select-link[aria-pressed="true"] { color: var(--ink); }

/* Group select-all. Sits in the same gutter as the row checkboxes so
   "everything under this heading" is one click and the rows never shift. */
.gpick {
  position: absolute; left: -22px; top: 2px;
  width: 18px; height: 18px;
  border-radius: var(--radius-xs);
  border: 1px solid var(--ink-ghost);
  background: var(--paper-raised);
  display: none; place-items: center;
  color: transparent; cursor: pointer; padding: 0;
}
/* Scoped, not body-level (0076): an /explore thread has one select scope per
   answer, and `body.is-picking` is true while ANY of them is open — so a
   body-level rule would reveal every other answer's group boxes the moment one
   reader started selecting in one. `.picking` lands on the scope itself. */
.picking .gpick { display: grid; }
.gpick:hover { border-color: var(--ink-muted); }
.gpick.is-all { background: var(--ink); border-color: var(--ink); color: var(--paper); }
/* Partial reads as a dash, never a tick. A group's items can be selected from
   another group without anyone touching this heading, so "some" is a real
   state — and a binary control would show the group as unselected while some
   of its rows are checked. */
.gpick.is-some { border-color: var(--ink); }
.gpick.is-some::after {
  content: ""; position: absolute; left: 3px; right: 3px; height: 2px;
  background: var(--ink); border-radius: 1px;
}

.bulkbar {
  position: fixed; left: 50%; bottom: 22px; transform: translateX(-50%);
  z-index: 60;
  display: flex; align-items: center; gap: 8px;
  padding: 10px 12px 10px 16px;
  border-radius: var(--radius-md);
  background: var(--ink); color: var(--paper);
  box-shadow: 0 12px 34px rgba(26, 26, 26, 0.28);
  font-family: var(--font-sans); font-size: 13.5px;
}
.bulkbar[hidden] { display: none; }
.bulkbar .selcount { font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.bulkbar .sep { width: 1px; align-self: stretch; background: rgba(251, 250, 247, 0.22); }
.sbtn {
  font-family: var(--font-sans); font-size: 13px; font-weight: 500;
  padding: 7px 12px;
  border-radius: var(--radius-sm);
  border: 1px solid rgba(251, 250, 247, 0.28);
  background: none; color: var(--paper);
  cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;
}
.sbtn:hover { background: rgba(251, 250, 247, 0.12); }
.sbtn.primary { background: var(--paper); color: var(--ink); border-color: var(--paper); }
.sbtn.primary:hover { background: var(--paper); opacity: 0.9; }
.sbtn.clear { color: rgba(251, 250, 247, 0.6); }
.sbtn[disabled] { opacity: 0.45; cursor: not-allowed; }
.sbtn[disabled]:hover { background: none; }

/* Bulk-action feedback. Floating UI, so it may cast a shadow (design rule 6).
   It sits above the bulk bar because it reports on what the bar just did, and
   the two are on screen together.

   This had NO css for its entire life: `select.js` set `.show` on an unstyled
   div, so every bulk message was invisible — including the shelf-cap refusal,
   which left "star 11 items" looking like a dead button with no explanation.
   Feedback nobody can see is the same as no feedback. */
.toast {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: 84px; z-index: 70;
  max-width: min(560px, calc(100vw - 32px));
  padding: 11px 16px;
  border-radius: var(--radius-md);
  background: var(--ink); color: var(--paper);
  font-family: var(--font-sans); font-size: 13.5px; line-height: 1.45;
  box-shadow: 0 12px 34px rgba(26, 26, 26, 0.28);
  opacity: 0; visibility: hidden;
  transition: opacity 160ms ease, visibility 160ms ease;
}
.toast.show { opacity: 1; visibility: visible; }

@media (prefers-reduced-motion: reduce) {
  .toast { transition: none; }
}

/* ---------- The bulk bar on a phone (spec 0075 § 6.1) ----------
   Ported from the design's `library.html`. The desktop bar is a centred pill
   sized to its contents, which on a phone runs off both edges — and the button
   that goes first is Done, the ONLY way out of bulk mode. § 6.1 named this as
   the one at risk for exactly that reason.

   Full-bleed and a grid instead: the count and the two mode controls on top, the
   primary action full-width, and the four item actions on one row. `grid-area`
   is keyed on `data-bulk` rather than the design's ids, since our bar is a
   partial rendering whichever actions its caller asked for. */
@media (max-width: 640px) {
  .bulkbar {
    left: 0; right: 0; bottom: 0; transform: none;
    border-radius: 14px 14px 0 0;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    grid-template-areas:
      "count count all done"
      "add   add   add add"
      "star  want  read del";
    gap: 8px;
    padding: 12px 12px calc(14px + env(safe-area-inset-bottom));
    box-shadow: 0 -10px 30px rgba(26, 26, 26, 0.26);
  }
  .bulkbar .sep { display: none; }
  .bulkbar .selcount { grid-area: count; align-self: center; }
  .bulkbar [data-bulk="all"] { grid-area: all; }
  .bulkbar [data-bulk="done"] { grid-area: done; }
  .bulkbar [data-bulk="collection"] {
    grid-area: add; justify-content: center; min-height: 46px; font-size: 14px;
  }
  .bulkbar [data-bulk="starred"] { grid-area: star; }
  .bulkbar [data-bulk="want_to_read"] { grid-area: want; }
  .bulkbar [data-bulk="mark_read"] { grid-area: read; }
  .bulkbar [data-bulk="delete"] { grid-area: del; }
  /* The collection page's bar is a different, shorter set — `remove` alone
     (0072 § 6) — and `collections.css` has no mobile rule for it at all: its
     only media query is 820px and never touches `.bulkbar`. So the LAYOUT is
     ours, but the behaviour is not allowed to differ: full-bleed at the bottom,
     safe-area padding, and Done always on screen, which is the whole point.
     A wrap rather than the grid above, because a template named for /items'
     five actions has no cell for this one. */
  .bulkbar:has([data-bulk="remove"]) {
    display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
    grid-template-areas: none;
  }
  .bulkbar:has([data-bulk="remove"]) .selcount { flex: 1 1 100%; }
  .bulkbar:has([data-bulk="remove"]) .sbtn { flex: 1 1 auto; }
  /* Four actions across a phone need the label to fit; the icon carries less
     here than the word does. */
  .bulkbar .sbtn { justify-content: center; padding: 9px 6px; font-size: 12.5px; }
  .bulkbar .sbtn i { display: none; }
  .bulkbar [data-bulk="collection"] i { display: inline-flex; }
}

/* The bar floats over the foot of the list, so the list needs room under it. */
body.is-picking main { padding-bottom: 104px; }

/* Narrow screens are the one place the gutter does not fit: hanging 22px into
   a 28px page margin leaves the box almost touching the screen edge and a
   thumb-sized target off it entirely. So the checkbox comes inside and the
   rows indent — but only while picking, so the resting list still lines up
   with the header above it. Matches the design's `library.html`.

   `.gpick` is deliberately not included: no template renders one yet (0076
   builds the tally headings), and moving it inside without markup to check
   against would put it under its own heading text. */
@media (max-width: 760px) {
  .item .pick {
    left: 2px;
    width: 22px; height: 22px;
    border-radius: var(--radius-sm);
  }
  /* Thumb target, without growing the visible box. */
  .item .pick::after { content: ""; position: absolute; inset: -11px; }
  .picking .item { padding-left: 36px; }
}

/* ---------- Result groups in an agent answer (spec 0076 § 1) ----------
   Ported from the design's `answer.css`. One shape for both result kinds: a
   tally is groups with labels, a list is one group without one. The rows inside
   are the canonical row, unchanged. */
.group { margin: 0 0 6px; }
.group + .group { margin-top: 34px; }
.group-head {
  position: relative;
  display: flex; align-items: baseline; gap: 12px;
  padding: 0 12px 6px 6px;
  border-bottom: 1px solid var(--ink-ghost);
}
.group-title {
  font-family: var(--font-serif); font-weight: 500;
  font-size: 21px; line-height: 1.25;
  color: var(--ink-soft); text-decoration: none; letter-spacing: -0.005em;
}
a.group-title:hover { color: var(--ink); box-shadow: inset 0 -0.35em 0 var(--highlight-wash); }
.group-spacer { flex: 1; }
.group .count {
  font-family: var(--font-sans); font-size: 12.5px; font-weight: 500;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
  padding: 2px 4px; margin: 0 -4px;
}

/* A truncated group keeps its surplus in the DOM and folds it away. That is
   load-bearing rather than cosmetic: `select.js` filters select-all to VISIBLE
   rows, so "select all" can only mean what it says if the rest is present and
   merely unseen (§ 2.1). */
.group[data-truncated] .item[data-extra] { display: none; }
.group.is-open .item[data-extra] { display: grid; }
.showall {
  display: flex; align-items: center; gap: 7px;
  width: 100%; margin-top: 2px; padding: 9px 12px;
  border: 0; background: none; border-radius: var(--radius-sm);
  font-family: var(--font-sans); font-size: 12.5px; font-weight: 500;
  color: var(--ink-muted); cursor: pointer; text-align: left;
}
.showall:hover { background: var(--highlight-faint); color: var(--ink); }
.showall i { color: var(--ink-faint); transition: transform var(--dur-fast) ease; }
.group.is-open .showall i { transform: rotate(180deg); }
/* Beyond what the turn carried at all — no expand can reveal these. */
.group-more {
  margin: 6px 12px 0;
  font-family: var(--font-sans); font-size: 12px; color: var(--ink-faint);
}

/* The one line that answers "why is THIS item here". Sans and quiet, above the
   item's own serif description: two different voices, and the order is the
   argument — why it is here, then what it is. */
.because {
  grid-column: 1 / -1;
  display: flex; align-items: center; gap: 6px;
  margin: 4px 0 0;
  font-family: var(--font-sans); font-size: 12.5px; color: var(--ink-muted);
}
.because i { color: var(--ink-faint); flex: none; }
/* The count of an item's relationships (issue #298). It sits in `.because` —
   on a most-connected answer the count IS the reason the row is there. */
.row-edges { color: var(--ink-muted); text-decoration: none; }
.because .row-edges strong { font-weight: 600; }
.row-edges:hover { color: var(--ink); box-shadow: inset 0 -0.35em 0 var(--highlight-wash); }
