/* Public quotes library — sharpthought.app/quotes
   (docs/quotes-platform-plan.md §5, docs/design.md tokens).

   Shares the landing site's visual system on purpose: same tokens, same
   background layers, same Newsreader/Manrope pairing, same topbar and
   footer. This file is standalone rather than an import of styles.css so
   the quotes section stays deployable on its own, but any token change
   in docs/design.md belongs in both. */

@import url("/topbar.css");

:root {
  --paper: #f4efe6;
  --paper2: #ece4d5;
  --card: #fbf7ef;
  --ink: #221e18;
  --ink2: #5c5346;
  --ink3: #8a8072;
  --clay: #b05a37;
  --clay2: #c9744e;
  --sage: #7c8466;
  --hairline: rgba(34, 30, 24, 0.14);
  --font-display: "Newsreader", Georgia, "Times New Roman", serif;
  --font-body: "Manrope", system-ui, -apple-system, sans-serif;
  --ease-out: cubic-bezier(0.05, 0.7, 0.1, 1);
  --motion-fast: 180ms;
  --motion-std: 400ms;
  --shell: 1080px;
  --measure: 42rem;
}

* {
  box-sizing: border-box;
}

html {
  text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

/* ── Background layers (mirrors the landing page) ─────────────── */

.paper-grid {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  opacity: 0.52;
  background-image:
    linear-gradient(rgba(34, 30, 24, 0.045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(34, 30, 24, 0.045) 1px, transparent 1px);
  background-size: 54px 54px;
  -webkit-mask-image: linear-gradient(to bottom, black 0%, transparent 94%);
  mask-image: linear-gradient(to bottom, black 0%, transparent 94%);
}

.hero-bg {
  position: absolute;
  inset: 0;
  height: 560px;
  pointer-events: none;
  z-index: 0;
  background-image:
    radial-gradient(circle at 100% 0%, rgba(201, 116, 78, 0.18), transparent 42%),
    linear-gradient(
      135deg,
      rgba(176, 90, 55, 0.1) 0%,
      rgba(244, 239, 230, 0.85) 50%,
      rgba(124, 132, 102, 0.12) 100%
    );
}

.grain {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 1;
  opacity: 0.05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)' opacity='1'/%3E%3C/svg%3E");
}

main,
.topbar,
.footer {
  position: relative;
  z-index: 5;
}

/* ── Base type ─────────────────────────────────────────────────── */

a {
  color: var(--clay);
  text-decoration: none;
}

a:hover {
  color: var(--clay2);
  text-decoration: underline;
  text-underline-offset: 3px;
}

:where(a, button, input, textarea):focus-visible {
  outline: 2px solid var(--clay);
  outline-offset: 3px;
}

.muted {
  color: var(--ink3);
}

.small {
  font-size: 0.85em;
}

.dotsep {
  margin: 0 8px;
  color: var(--ink3);
}

.skip-link {
  position: fixed;
  top: 12px;
  left: 12px;
  z-index: 20;
  padding: 10px 14px;
  border-radius: 10px;
  background: var(--ink);
  color: var(--paper);
  transform: translateY(-160%);
}

.skip-link:focus {
  color: var(--paper);
  transform: translateY(0);
}

/* ── Topbar ────────────────────────────────────────────────────── */

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
  max-width: var(--shell);
  margin: 0 auto;
  padding: 18px 24px;
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(244, 239, 230, 0.92);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--hairline);
}

/* The wordmark and the app CTA live in topbar.css, shared with the
   landing page — they had drifted into two different-looking brands. */
.topnav {
  display: flex;
  align-items: center;
  gap: 4px 22px;
  flex-wrap: wrap;
  font-size: 15px;
}

.topnav a {
  color: var(--ink2);
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}

.topnav a:hover {
  color: var(--clay);
  text-decoration: none;
}

.topnav a[aria-current="page"] {
  color: var(--ink);
  font-weight: 600;
  box-shadow: inset 0 -2px 0 var(--clay);
}

/* ── Page scaffolding ──────────────────────────────────────────── */

main {
  max-width: var(--shell);
  margin: 0 auto;
  padding: 0 24px 96px;
}

.page-head {
  max-width: var(--measure);
  padding: 56px 0 12px;
}

.page-head-wide {
  max-width: 46rem;
}

/* Books, Authors and the quote hub share one head: full width, a title
   that fits on a line and a single line of standfirst under it, so the
   grid starts near the top of the viewport instead of below the fold. */
.page-head-catalog {
  max-width: none;
  padding: 44px 0 4px;
}

.page-head-catalog .eyebrow {
  margin-bottom: 12px;
}

.page-head-catalog .page-title {
  font-size: clamp(30px, 3.6vw, 40px);
  margin-bottom: 10px;
}

.page-head-catalog .page-sub {
  max-width: 62rem;
  font-size: 16.5px;
  margin-bottom: 0;
}

.page-head-catalog .page-actions {
  margin-top: 20px;
}

.eyebrow {
  font-size: 12.5px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--clay);
  margin: 0 0 18px;
  font-weight: 600;
}

.page-title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(34px, 5.4vw, 54px);
  line-height: 1.08;
  letter-spacing: -0.015em;
  margin: 0 0 20px;
}

.page-sub {
  font-size: 17.5px;
  color: var(--ink2);
  margin: 0 0 24px;
  max-width: 38rem;
}

.page-stat {
  font-size: 14px;
  color: var(--ink3);
  margin: 20px 0 0;
  font-variant-numeric: tabular-nums;
}

.page-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin: 26px 0 0;
}

/* ── Buttons ───────────────────────────────────────────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 11px 22px;
  border-radius: 999px;
  border: 1px solid var(--ink);
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-weight: 600;
  font-size: 15px;
  cursor: pointer;
  transition:
    background var(--motion-fast) var(--ease-out),
    border-color var(--motion-fast) var(--ease-out),
    transform var(--motion-fast) var(--ease-out);
}

.btn:hover {
  text-decoration: none;
  background: var(--paper2);
  color: var(--ink);
}

.btn:active {
  transform: translateY(1px);
}

.btn-primary {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
}

.btn-primary:hover {
  background: var(--clay);
  border-color: var(--clay);
  color: var(--paper);
}

.btn-buy {
  background: var(--clay);
  border-color: var(--clay);
  color: var(--paper);
}

.btn-buy:hover {
  background: var(--clay2);
  border-color: var(--clay2);
  color: var(--paper);
}

.btn-quiet {
  border-color: var(--hairline);
  color: var(--ink2);
  background: var(--card);
}

.btn-quiet:hover {
  border-color: var(--ink3);
  color: var(--ink);
}

.btn:disabled {
  opacity: 0.55;
  cursor: default;
  transform: none;
}

/* ── Bands and chips ───────────────────────────────────────────── */

.band {
  margin: 56px 0 0;
}

.band-title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 15px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink3);
  margin: 0 0 20px;
}

.band-more {
  margin: 20px 0 0;
  font-size: 15px;
}

.chips {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.chips a {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 16px;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  background: var(--card);
  color: var(--ink2);
  font-size: 14.5px;
  font-weight: 500;
  transition:
    border-color var(--motion-fast) var(--ease-out),
    background var(--motion-fast) var(--ease-out);
}

.chips a:hover {
  border-color: var(--clay);
  color: var(--ink);
  background: var(--paper2);
  text-decoration: none;
}

.chip-count {
  font-size: 12px;
  color: var(--ink3);
  font-variant-numeric: tabular-nums;
}

/* ── Quote cards ───────────────────────────────────────────────── */

.listing {
  margin: 48px 0 0;
}

.q-grid {
  display: grid;
  gap: 22px;
  grid-template-columns: repeat(auto-fill, minmax(19rem, 1fr));
}

.q-card {
  display: flex;
  flex-direction: column;
  background: var(--card);
  border: 1px solid var(--hairline);
  border-radius: 18px;
  padding: 26px 24px 18px;
  transition:
    border-color var(--motion-std) var(--ease-out),
    box-shadow var(--motion-std) var(--ease-out),
    transform var(--motion-std) var(--ease-out);
}

.q-card:hover {
  border-color: rgba(176, 90, 55, 0.45);
  box-shadow: 0 18px 38px -26px rgba(34, 30, 24, 0.5);
  transform: translateY(-2px);
}

.q-card-link {
  color: inherit;
  display: block;
  flex: 1;
}

.q-card-link:hover {
  text-decoration: none;
  color: inherit;
}

.q-card-text {
  font-family: var(--font-display);
  font-size: 18.5px;
  line-height: 1.42;
  margin: 0 0 16px;
  color: var(--ink);
  quotes: "“" "”";
}

.q-card-text::before {
  content: open-quote;
}

.q-card-text::after {
  content: close-quote;
}

.q-card-author {
  margin: 0;
  font-weight: 600;
  font-size: 14.5px;
  color: var(--ink);
}

.q-card-cite {
  margin: 4px 0 0;
  font-size: 13.5px;
  color: var(--ink3);
  font-style: italic;
  font-family: var(--font-display);
}

.q-card-theme {
  margin: 16px 0 0;
  padding-top: 14px;
  border-top: 1px solid var(--hairline);
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.q-card-theme a {
  color: var(--ink3);
  font-weight: 600;
}

.q-card-theme a:hover {
  color: var(--clay);
  text-decoration: none;
}

/* ── Theme and author cards ────────────────────────────────────── */

.t-grid,
.a-grid {
  display: grid;
  gap: 20px;
  margin: 40px 0 0;
}

.t-grid {
  grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
}

.a-grid {
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
}

.t-card,
.a-card {
  display: block;
  background: var(--card);
  border: 1px solid var(--hairline);
  border-radius: 18px;
  padding: 26px 24px;
  color: inherit;
  transition:
    border-color var(--motion-std) var(--ease-out),
    box-shadow var(--motion-std) var(--ease-out),
    transform var(--motion-std) var(--ease-out);
}

.t-card:hover,
.a-card:hover {
  border-color: rgba(176, 90, 55, 0.45);
  box-shadow: 0 18px 38px -26px rgba(34, 30, 24, 0.5);
  transform: translateY(-2px);
  text-decoration: none;
  color: inherit;
}

.t-card-title,
.a-card-name {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 24px;
  margin: 0 0 10px;
  letter-spacing: -0.01em;
}

.t-card-blurb {
  margin: 0 0 16px;
  color: var(--ink2);
  font-size: 15px;
}

.t-card-meta,
.a-card-meta {
  margin: 0;
  font-size: 13.5px;
  color: var(--ink3);
  font-variant-numeric: tabular-nums;
}

.a-card-works {
  margin: 10px 0 0;
  font-family: var(--font-display);
  font-style: italic;
  font-size: 13.5px;
  color: var(--ink3);
}

/* ── Empty state ───────────────────────────────────────────────── */

.q-empty {
  background: var(--card);
  border: 1px dashed var(--hairline);
  border-radius: 18px;
  padding: 40px 28px;
  max-width: var(--measure);
  color: var(--ink2);
}

.q-empty-title {
  font-family: var(--font-display);
  font-size: 21px;
  color: var(--ink);
  margin: 0 0 12px;
}

.q-empty p {
  margin: 0 0 14px;
}

/* ── Quote page ────────────────────────────────────────────────── */

/* A single quote is long-form reading, so the page sits centred in
   the shell (same width as the listing pages). Inner blocks still wrap
   at the readable measure so line length stays comfortable. */
.q-page {
  max-width: var(--shell);
  margin: 0 auto;
  padding: 48px 0 0;
}

.q-hero {
  margin: 0 0 40px;
}

.q-text {
  font-family: var(--font-display);
  font-size: clamp(27px, 4.6vw, 40px);
  line-height: 1.24;
  letter-spacing: -0.015em;
  margin: 0 0 24px;
  color: var(--ink);
  quotes: "“" "”";
}

.q-text::before {
  content: open-quote;
}

.q-text::after {
  content: close-quote;
}

.q-attrib {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 0;
  font-size: 15.5px;
}

.q-attrib-author {
  font-weight: 700;
  color: var(--ink);
  font-size: 17px;
}

.q-attrib-author:hover {
  color: var(--clay);
}

.q-attrib-cite,
.q-attrib-trans {
  font-family: var(--font-display);
  font-style: italic;
  color: var(--ink2);
}

.q-verified {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 20px 0 0;
  padding: 7px 15px;
  border-radius: 999px;
  background: rgba(124, 132, 102, 0.14);
  border: 1px solid rgba(124, 132, 102, 0.4);
  color: #5f6650;
  font-size: 13px;
  font-weight: 600;
}

.q-verified-mark {
  font-weight: 700;
}

/* Corrections (plan §10). Clay rather than sage: this badge says "careful",
   where .q-verified says "checked". They must never be mistaken for each
   other — that confusion is the failure mode the library exists to avoid. */
.q-disputed {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 20px 0 0;
  padding: 7px 15px;
  border-radius: 999px;
  background: rgba(176, 90, 55, 0.1);
  border: 1px solid rgba(176, 90, 55, 0.38);
  color: var(--clay);
  font-size: 13px;
  font-weight: 600;
}

.q-disputed-mark {
  font-weight: 700;
}

.q-corrections {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 22px;
}

.q-correction {
  border: 1px solid var(--hairline);
  border-radius: 16px;
  padding: 24px 26px;
  background: var(--card);
}

.q-correction-text {
  margin: 0 0 14px;
  font-family: var(--font-display, Newsreader), Georgia, serif;
  font-style: italic;
  font-size: 21px;
  line-height: 1.45;
  color: var(--ink);
}

.q-correction-text a {
  color: inherit;
  text-decoration: none;
}

.q-correction-text a:hover {
  text-decoration: underline;
}

.q-correction-attrib {
  margin: 0 0 8px;
  font-size: 13px;
  color: var(--ink3);
}

.q-correction-note {
  margin: 0;
  font-size: 15px;
  line-height: 1.6;
  color: var(--ink2);
}

.q-correction-source {
  margin: 12px 0 0;
  font-size: 13px;
}

.q-note {
  background: rgba(176, 90, 55, 0.07);
  border: 1px solid rgba(176, 90, 55, 0.3);
  border-radius: 14px;
  padding: 20px 22px;
  margin: 0 0 36px;
}

.q-note-title {
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--clay);
  margin: 0 0 8px;
  font-weight: 700;
}

.q-note p {
  margin: 0;
  color: var(--ink2);
  font-size: 15.5px;
}

.q-block {
  margin: 0 0 40px;
  padding-top: 32px;
  border-top: 1px solid var(--hairline);
}

.q-block-title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 14px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink3);
  margin: 0 0 16px;
}

.q-block p {
  margin: 0 0 14px;
  font-size: 17px;
  color: var(--ink2);
}

.q-block p:last-child {
  margin-bottom: 0;
}

.q-original {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 19px !important;
  color: var(--ink) !important;
}

.q-method {
  margin: 0;
  display: grid;
  gap: 6px 20px;
  grid-template-columns: max-content 1fr;
}

.q-method dt {
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--clay);
  font-weight: 700;
  padding-top: 4px;
}

.q-method dd {
  margin: 0 0 10px;
  color: var(--ink2);
  font-size: 16.5px;
}

.q-source-work {
  font-family: var(--font-display);
  font-size: 17px !important;
  color: var(--ink) !important;
}

.q-links {
  list-style: none;
  padding: 0;
  margin: 18px 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.q-affiliate,
.q-source-line {
  font-size: 13.5px !important;
  color: var(--ink3) !important;
  margin: 18px 0 0 !important;
}

/* ── Reflection box ────────────────────────────────────────────── */

.q-prompt {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 21px !important;
  color: var(--ink) !important;
  margin: 0 0 18px !important;
}

.q-reflect textarea {
  width: 100%;
  min-height: 8rem;
  padding: 18px;
  border: 1px solid var(--hairline);
  border-radius: 14px;
  background: var(--card);
  font-family: var(--font-body);
  font-size: 16.5px;
  line-height: 1.6;
  color: var(--ink);
  resize: vertical;
  transition: border-color var(--motion-fast) var(--ease-out);
}

.q-reflect textarea::placeholder {
  color: var(--ink3);
}

.q-reflect textarea:focus {
  outline: none;
  border-color: var(--clay);
}

.q-reflect-note {
  font-size: 13.5px !important;
  color: var(--ink3) !important;
  margin: 12px 0 0 !important;
}

.q-saved {
  color: var(--sage);
  font-weight: 600;
}

.q-saved:not(:empty) {
  margin-right: 8px;
}

.q-resonance {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  margin: 24px 0 0 !important;
}

.q-related {
  padding-top: 32px;
}

.q-related .q-grid {
  grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
  gap: 18px;
}

/* ── Join banner (the funnel, plan §5.6) ───────────────────────── */

.join {
  margin: 56px 0;
  background: linear-gradient(160deg, #faf6ee 0%, var(--paper2) 100%);
  border: 1px solid var(--hairline);
  border-radius: 24px;
  box-shadow: 0 26px 60px -40px rgba(34, 30, 24, 0.6);
  overflow: hidden;
}

/* Single column is the base (phones and narrow tablets): the pitch reads
   top to bottom and fills the card. No measure cap is needed here — this
   mode only runs below 860px, where the card is at most ~740px wide and
   the line length is comfortable on its own. Above that the card splits
   into two columns; see the min-width rule below. */
.join-inner {
  padding: 40px 34px 34px;
}

.join-eyebrow {
  font-size: 12px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--clay);
  font-weight: 700;
  margin: 0 0 16px;
}

.join-title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(25px, 3.6vw, 34px);
  line-height: 1.16;
  letter-spacing: -0.015em;
  margin: 0 0 16px;
  color: var(--ink);
}

.join-sub {
  font-size: 16.5px;
  color: var(--ink2);
  margin: 0 0 26px;
}

.join-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin: 0 0 26px;
}

.join-points {
  list-style: none;
  padding: 0;
  margin: 0 0 18px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px 22px;
  font-size: 14px;
  color: var(--ink2);
}

.join-points li {
  display: flex;
  align-items: center;
  gap: 8px;
}

.join-points li::before {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--sage);
  flex: none;
}

.join-fine {
  font-size: 13px;
  color: var(--ink3);
  margin: 0;
}

/* Two columns once the card is wide enough to hold them: the pitch on
   the left at a readable measure, the offer (buttons, points, fine
   print) on the right. Before this the block capped at 40rem inside a
   ~1030px card and stranded 390px of empty card on every quotes page.
   860px is where both columns still clear their content — the two CTAs
   sit side by side and the pitch keeps ~60 characters a line. */
@media (min-width: 860px) {
  .join-inner {
    display: grid;
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
    align-items: start;
    gap: 44px;
  }

  /* Last block in its column, so the stacking margin is dead weight. */
  .join-sub {
    margin-bottom: 0;
  }

  /* One per line: the column is too narrow to wrap four points evenly,
     and a ragged two-and-two row reads as an accident. */
  .join-points {
    flex-direction: column;
    gap: 10px;
  }
}

/* ── Footer ────────────────────────────────────────────────────── */

.footer {
  border-top: 1px solid var(--hairline);
  background: var(--paper2);
  padding: 44px 24px 52px;
}

.footer-inner {
  max-width: var(--shell);
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
  text-align: center;
}

.footer-claim {
  margin: 0;
  font-family: var(--font-display);
  font-size: 17px;
  color: var(--ink);
}

.footer-claim .muted {
  font-style: italic;
  font-size: 15px;
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 4px 22px;
  font-size: 14px;
}

.footer-links a {
  color: var(--ink2);
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}

.footer-links a:hover {
  color: var(--clay);
}

.footer-meta {
  font-size: 14px;
  color: var(--ink2);
  margin: 0;
}

.footer-sep {
  margin: 0 8px;
}

/* ── Responsive ────────────────────────────────────────────────── */

@media (max-width: 760px) {
  main {
    padding: 0 20px 72px;
  }

  .topbar {
    padding: 20px 20px 0;
  }

  .page-head {
    padding-top: 40px;
  }

  .q-grid {
    grid-template-columns: 1fr;
  }

  .join-inner {
    padding: 32px 24px 28px;
  }

  .q-method {
    grid-template-columns: 1fr;
    gap: 2px;
  }

  .q-method dd {
    margin-bottom: 16px;
  }
}

@media (max-width: 460px) {
  .page-actions .btn,
  .join-actions .btn {
    width: 100%;
  }

  .q-links .btn {
    width: 100%;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    transition-duration: 1ms !important;
    animation-duration: 1ms !important;
  }

  .q-card:hover,
  .t-card:hover,
  .a-card:hover {
    transform: none;
  }
}

/* Database-backed homepage and editorial sections share the public reading rhythm. */
.q-section { margin: 48px 0; }
.q-section > h2 { margin-bottom: 24px; font-size: clamp(26px, 4vw, 38px); }
.q-section p { line-height: 1.8; overflow-wrap: anywhere; }
.q-section .q-card h3 { margin-block: 10px 16px; font-size: 26px; }
.page-actions label { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.page-actions input, .page-actions select { max-width: 100%; min-height: 44px; padding: 8px 12px; background: var(--card); color: var(--ink); border: 1px solid var(--hairline); border-radius: 8px; font: inherit; }
@media (max-width: 600px) { .page-actions label { width: 100%; } .q-section { margin-block: 32px; } }

/* ── Catalog layout: side rail + grid ──────────────────────────────
   Authors and Books borrow the illustrated card grid from /journal, but
   their filters move into a narrow left rail instead of a full-width
   form above the results (docs/completed/public-catalog-ui-refine.md).
   Below 900px the rail becomes a short horizontal band above the grid,
   so the first thing on a phone is still the catalog. */

.catalog-layout {
  display: grid;
  grid-template-columns: 15rem minmax(0, 1fr);
  gap: 44px;
  align-items: start;
  margin: 36px 0 0;
}

.catalog-rail {
  position: sticky;
  /* Clears the pinned topbar (86px on desktop) so the rail stops below
     it rather than sliding underneath. */
  top: 102px;
  display: flex;
  flex-direction: column;
  gap: 26px;
  padding: 22px 20px;
  background: var(--card);
  border: 1px solid var(--hairline);
  border-radius: 16px;
}

.rail-label {
  display: block;
  margin: 0 0 10px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink3);
}

.rail-search {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.rail-search input {
  box-sizing: border-box;
  width: 100%;
  min-width: 0;
  min-height: 40px;
  padding: 9px 12px;
  border: 1px solid var(--hairline);
  border-radius: 9px;
  background: var(--paper);
  color: var(--ink);
  font: 400 15px/1.4 var(--font-body);
}

.rail-search input::placeholder {
  color: var(--ink3);
  opacity: 1;
}

.rail-submit {
  min-height: 40px;
  padding-inline: 16px;
  font-size: 14px;
}

.rail-group {
  margin: 0;
}

.rail-letters,
.rail-options {
  list-style: none;
  margin: 0;
  padding: 0;
}

.rail-letters {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.rail-letters a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 30px;
  min-height: 30px;
  padding: 0 7px;
  border: 1px solid transparent;
  border-radius: 8px;
  color: var(--ink2);
  font-size: 13.5px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  transition:
    background var(--motion-fast) var(--ease-out),
    border-color var(--motion-fast) var(--ease-out);
}

.rail-options {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.rail-options a {
  display: block;
  padding: 7px 10px;
  border: 1px solid transparent;
  border-radius: 8px;
  color: var(--ink2);
  font-size: 14.5px;
}

.rail-letters a:hover,
.rail-options a:hover {
  background: var(--paper2);
  color: var(--ink);
  text-decoration: none;
}

.rail-letters a[aria-current],
.rail-options a[aria-current] {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
}

.rail-clear {
  margin: 0;
  font-size: 13.5px;
}

/* How much the grid is showing. It reads as a caption on the panel
   rather than a heading over the results, which is where the old
   "25 authors on this page" line sat. */
.rail-count {
  margin: 0;
  padding-top: 18px;
  border-top: 1px solid var(--hairline);
  font-size: 13px;
  color: var(--ink3);
  font-variant-numeric: tabular-nums;
}

.catalog-main {
  min-width: 0;
}

.catalog-main .page-stat {
  margin: 0 0 8px;
}

.catalog-main .a-grid {
  margin-top: 20px;
}

.catalog-pager {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin: 36px 0 0;
}

/* ── Author cards with a portrait ──────────────────────────────── */

.a-portrait {
  display: block;
  width: 72px;
  height: 72px;
  margin: 0 0 16px;
  border-radius: 999px;
  border: 1px solid var(--hairline);
  background: var(--paper2);
  object-fit: cover;
}

/* Real cleared portraits are photographs; the generic avatars are the
   committed brand SVGs and already sit in the paper palette. */
.a-portrait-generic {
  border-color: transparent;
}

/* ── Book cards ────────────────────────────────────────────────── */

.b-grid {
  display: grid;
  gap: 22px;
  grid-template-columns: repeat(auto-fill, minmax(21rem, 1fr));
  margin: 20px 0 0;
}

.b-card {
  display: grid;
  grid-template-columns: 104px minmax(0, 1fr);
  gap: 8px 20px;
  align-content: start;
  background: var(--card);
  border: 1px solid var(--hairline);
  border-radius: 18px;
  padding: 24px;
  transition:
    border-color var(--motion-std) var(--ease-out),
    box-shadow var(--motion-std) var(--ease-out);
}

.b-card:hover {
  border-color: rgba(176, 90, 55, 0.45);
  box-shadow: 0 18px 38px -26px rgba(34, 30, 24, 0.5);
}

.b-card-art {
  grid-row: span 2;
}

/* The jacket is generated, not scanned — greyscale is belt and braces so
   a later coloured source cannot break the black-and-white shelf. */
.b-cover {
  display: block;
  width: 104px;
  height: 156px;
  border-radius: 4px 10px 10px 4px;
  filter: grayscale(1);
  box-shadow: 0 10px 22px -14px rgba(34, 30, 24, 0.75);
}

.b-card-body {
  min-width: 0;
}

.b-card-title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 23px;
  line-height: 1.2;
  letter-spacing: -0.01em;
  margin: 0 0 6px;
  overflow-wrap: anywhere;
}

.b-card-meta {
  margin: 0 0 10px;
  font-size: 13.5px;
  color: var(--ink3);
  font-variant-numeric: tabular-nums;
}

.b-edition-note {
  margin: 0 0 14px;
  font-size: 13.5px;
  color: var(--ink2);
}

.b-card-cta {
  margin: 0;
}

/* Secondary action: a link, not a second button, so the purchase edition
   stays the one obvious thing to click. */
.b-card-secondary {
  margin: 12px 0 0;
  font-size: 14.5px;
}

.b-card-foot {
  grid-column: 2;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px 16px;
  margin: 16px 0 0;
  padding-top: 14px;
  border-top: 1px solid var(--hairline);
  font-size: 13.5px;
}

.b-card-count {
  white-space: nowrap;
  color: var(--ink3);
  font-variant-numeric: tabular-nums;
}

.b-card-quotes-link {
  font-weight: 600;
}

@media (max-width: 900px) {
  .catalog-layout {
    grid-template-columns: minmax(0, 1fr);
    gap: 28px;
  }

  .catalog-rail {
    position: static;
    top: auto;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 18px 28px;
  }

  .rail-search {
    flex: 1 1 15rem;
  }

  .rail-options {
    flex-direction: row;
    flex-wrap: wrap;
    gap: 6px;
  }
}

@media (max-width: 560px) {
  .b-card {
    grid-template-columns: 76px minmax(0, 1fr);
    gap: 16px;
    padding: 20px;
  }

  .b-cover {
    width: 76px;
    height: 114px;
  }

  .b-card-art {
    grid-row: 1;
  }

  .b-card-foot {
    grid-column: 1 / -1;
  }
}

/* ── Today's quote ─────────────────────────────────────────────────
   Sits above the catalog on /quotes. The dismiss control hides it for
   this browser until the daily quote changes; see public/quotes.js. */

.q-today {
  display: flex;
  align-items: flex-start;
  gap: 20px;
  margin: 28px 0 0;
  padding: 26px 28px;
  background: linear-gradient(160deg, #faf6ee 0%, var(--paper2) 100%);
  border: 1px solid var(--hairline);
  border-radius: 18px;
}

/* `display: flex` above outranks the user-agent [hidden] rule, so the
   dismiss control has to be told explicitly. */
.q-today[hidden] {
  display: none;
}

.q-today-body {
  flex: 1;
  min-width: 0;
}

.q-today-label {
  margin: 0 0 12px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--clay);
}

.q-today-text {
  margin: 0 0 14px;
  font-family: var(--font-display);
  font-size: clamp(20px, 2.6vw, 26px);
  line-height: 1.34;
  color: var(--ink);
  quotes: "\201C" "\201D";
}

.q-today-text::before {
  content: open-quote;
}

.q-today-text::after {
  content: close-quote;
}

.q-today-text a {
  color: inherit;
}

.q-today-text a:hover {
  color: var(--clay);
  text-decoration: none;
}

.q-today-attrib {
  margin: 0;
  font-size: 14.5px;
  font-weight: 600;
  color: var(--ink2);
}

.q-today-cite {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  color: var(--ink3);
}

.q-today-dismiss {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  background: transparent;
  color: var(--ink3);
  font-size: 19px;
  line-height: 1;
  cursor: pointer;
  transition:
    background var(--motion-fast) var(--ease-out),
    color var(--motion-fast) var(--ease-out);
}

.q-today-dismiss:hover {
  background: var(--card);
  color: var(--ink);
}

@media (max-width: 560px) {
  .q-today {
    padding: 22px;
    gap: 12px;
  }
}
