/* Sources page — the searchable catalogue. */

.page-head {
  padding: clamp(2.5rem, 6vw, 4rem) 0 1.75rem;
  border-bottom: 1px solid var(--border);
  background: var(--bg-tint);
}
.page-head .lede {
  max-width: 46rem;
  margin-bottom: 0;
}

/* ------------------------------------------------------------- controls -- */

/* Sticky under the nav so the filters stay reachable 600 cards down. */
/* Bounds the sticky controls below. Without it the bar's containing block is
   <main>, so it stayed pinned over the request form at the foot of the page. */
.catalogue {
  position: relative;
}

/* Clears the site header once the controls bar has scrolled away with the
   catalogue, so the heading is not tucked under it on arrival. */
#request {
  scroll-margin-top: 5rem;
}

.controls {
  position: sticky;
  top: 55px;
  z-index: 20;
  padding: 1rem 0 0.85rem;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid var(--border);
}

.searchbar {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  padding: 0.15rem 0.6rem 0.15rem 1rem;
  box-shadow: var(--shadow-tint);
  transition: border-color 0.18s var(--ease), box-shadow 0.18s var(--ease);
}
.searchbar:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.searchbar svg {
  width: 18px;
  height: 18px;
  flex: none;
  color: var(--text-faint);
}
.searchbar input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: 1rem;
  color: var(--text);
  padding: 0.7rem 0;
  outline: none;
}
.searchbar input::placeholder {
  color: var(--text-faint);
}
/* Safari draws its own clear affordance on type=search, which would sit next to
 * ours. */
.searchbar input::-webkit-search-cancel-button {
  display: none;
}
.searchbar__clear {
  flex: none;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border: 0;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--text-dim);
  cursor: pointer;
}
.searchbar__clear:hover {
  color: var(--text);
}
.searchbar__clear svg {
  width: 15px;
  height: 15px;
  color: inherit;
}

.filters {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  gap: 0.6rem;
  margin-top: 0.85rem;
}

.select {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  font-size: 0.72rem;
  font-weight: 650;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.select select {
  font: inherit;
  font-size: 0.9rem;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  padding: 0.42rem 0.85rem;
  cursor: pointer;
  max-width: 15rem;
}

.btn--sm {
  padding: 0.42rem 1rem;
  font-size: 0.88rem;
}

/* On a phone the four filters stack, and a sticky block that tall would eat
 * half the viewport the moment it stuck — so pair them up and let the whole bar
 * scroll away instead. */
@media (max-width: 720px) {
  .controls {
    position: static;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
  .filters {
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-items: end;
  }
  .select select {
    max-width: none;
    width: 100%;
  }
  .filters > .btn {
    grid-column: 1 / -1;
    justify-self: start;
  }
}

.count-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem 1rem;
  flex-wrap: wrap;
  margin-top: 0.85rem;
}

.count {
  margin: 0;
  font-size: 0.88rem;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}

/* The catalogue is 687 entries long and the request form sits after all of
   them. Because the controls bar is sticky, this link is the only thing on the
   page that offers the form without scrolling to the end to discover it. */
.request-link {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.88rem;
  font-weight: 600;
  white-space: nowrap;
}
.request-link svg {
  width: 15px;
  height: 15px;
  flex: none;
}
.request-link:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ---------------------------------------------------------------- cards -- */

.cards {
  list-style: none;
  margin: 1.75rem 0 0;
  padding: 0;
  display: grid;
  gap: 1.1rem;
  grid-template-columns: repeat(auto-fill, minmax(330px, 1fr));
}

.src {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 1.35rem 1.4rem 1.15rem;
  box-shadow: var(--shadow-tint);
}

.src__title {
  font-size: 1.06rem;
  font-weight: 660;
  letter-spacing: -0.015em;
  line-height: 1.32;
  margin: 0 0 0.2rem;
}

.src__author {
  font-size: 0.93rem;
  color: var(--text-dim);
  margin: 0 0 0.8rem;
}
.src__dates {
  color: var(--text-faint);
}

.src__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-bottom: 0.9rem;
}

.tag {
  font-size: 0.7rem;
  font-weight: 650;
  letter-spacing: 0.04em;
  padding: 0.2em 0.6em;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent);
  white-space: nowrap;
}
.tag--type {
  background: transparent;
  border: 1px solid var(--border-strong);
  color: var(--text-dim);
}
.tag--bundled {
  background: var(--gold-soft);
  color: var(--gold-ink);
}

/* The excerpt is the card's reason for existing, so it is typeset as text
 * rather than as metadata: serif, generous leading, a quotation rule. */
.src__excerpt {
  font-family: var(--serif);
  font-size: 0.97rem;
  line-height: 1.62;
  color: var(--text);
  margin: 0 0 1rem;
  padding-left: 0.9rem;
  border-left: 2px solid var(--border-strong);
  /* Long works get long openings; clamp so the grid stays even and the card
   * stays scannable. The full text is in the app. */
  display: -webkit-box;
  -webkit-line-clamp: 6;
  line-clamp: 6;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.src__meta {
  margin-top: auto;
  padding-top: 0.85rem;
  border-top: 1px solid var(--border);
  font-size: 0.82rem;
  color: var(--text-dim);
  display: grid;
  gap: 0.28rem;
}
.src__meta div {
  display: flex;
  gap: 0.45rem;
}
.src__meta dt {
  flex: none;
  min-width: 5.2rem;
  color: var(--text-faint);
}
.src__meta dd {
  margin: 0;
  min-width: 0;
  overflow-wrap: anywhere;
}

.src__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.9rem;
  margin-top: 0.85rem;
  font-size: 0.82rem;
}
.src__size {
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}
.src__link {
  margin-left: auto;
  font-weight: 600;
}

.empty {
  text-align: center;
  color: var(--text-dim);
  padding: 3.5rem 1rem;
  font-size: 1.02rem;
}

.more {
  display: flex;
  justify-content: center;
  padding: 2rem 0 0;
}

/* -------------------------------------------------------------- request -- */

.request {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
  gap: clamp(2rem, 5vw, 3.5rem);
  align-items: start;
}
@media (max-width: 860px) {
  .request {
    grid-template-columns: minmax(0, 1fr);
  }
}
.request p {
  color: var(--text-dim);
}

.form {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 1.6rem;
  box-shadow: var(--shadow-tint);
}

.form__row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.9rem;
}
@media (max-width: 520px) {
  .form__row {
    grid-template-columns: 1fr;
  }
}

.field {
  display: block;
  margin-bottom: 0.9rem;
}
.field > span {
  display: block;
  font-size: 0.82rem;
  font-weight: 620;
  color: var(--text-dim);
  margin-bottom: 0.3rem;
}
.field input,
.field textarea {
  width: 100%;
  font: inherit;
  font-size: 0.95rem;
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  padding: 0.65rem 0.85rem;
  outline: none;
  transition: border-color 0.18s var(--ease), box-shadow 0.18s var(--ease);
}
.field textarea {
  resize: vertical;
  min-height: 6rem;
}
.field input:focus,
.field textarea:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.field input::placeholder,
.field textarea::placeholder {
  color: var(--text-faint);
}

.form .btn {
  width: 100%;
  margin-top: 0.3rem;
}

.form__status {
  margin: 0.9rem 0 0;
  font-size: 0.9rem;
  text-align: center;
  min-height: 1.2em;
}
.form__status--ok {
  color: #15803d;
}
.form__status--err {
  color: #b91c1c;
}
:root[data-theme="dark"] .form__status--ok {
  color: #4ade80;
}
:root[data-theme="dark"] .form__status--err {
  color: #fca5a5;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .form__status--ok {
    color: #4ade80;
  }
  :root:not([data-theme]) .form__status--err {
    color: #fca5a5;
  }
}
