/* ============================================================
   Bookshelf page — filter rail, cover grid, floating book windows
   Requires shared.css for tokens, header, footer, 3D book.
   ============================================================ */

body { padding: 48px 48px 0; }

/* ---------- filter rail ---------- */

.filters {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 32px;
  max-width: 1400px;
  margin-bottom: 64px;
}

.filter-block { min-width: 0; }

/* the block is a <details> so it can collapse on a phone; on desktop it
   stays open and the disclosure affordance is suppressed entirely */
.filter-block > summary {
  list-style: none;
  display: block;
  cursor: default;
  /* not a control at this width — it can't be collapsed or focused */
  pointer-events: none;
}

.filter-block > summary::-webkit-details-marker { display: none; }
.filter-block > summary::marker { content: ""; }

.filter-head {
  display: block;
  font-size: inherit;
  font-weight: 400;
  font-style: italic;
  color: var(--ink-soft);
  padding-bottom: 8px;
  margin-bottom: 8px;
  border-bottom: 1px solid var(--rule);
}

.link-list { display: flex; flex-direction: column; align-items: flex-start; }

.link-list button {
  font: inherit;
  color: var(--ink-soft);
  background: none;
  border: 0;
  padding: 3px 0;
  text-align: left;
  cursor: pointer;
  transition: color 120ms ease;
}

.link-list button:hover { color: var(--ink); }

.link-list button[aria-pressed="true"] {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: color-mix(in srgb, var(--ink) 25%, transparent);
  text-underline-offset: 4px;
}

/* genres can run long — cap the list and scroll the overflow */
.filter-genres .link-list {
  max-height: 210px;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
}

/* ---------- the shelf ---------- */

.shelf {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 44px 28px;
  max-width: 1400px;
}

.book-cell {
  display: block;
  width: 100%;
  padding: 0;
  background: none;
  border: 0;
  cursor: pointer;
  text-align: left;
}

/* the grid cell owns the width; the 3D book fills it at 2:3 */
.book-cell .book-scene {
  --bw: 100%;
  --bh: auto;
  width: 100%;
  height: auto;
  aspect-ratio: 2 / 3;
}

/* hover transforms in shared.css scale with --bw, which is a
   percentage here — restate them against the cell's real width */
@media (hover: hover) and (pointer: fine) {
  .book-cell .book-scene:hover .b-image {
    transform: perspective(2000px) translateX(-5px) rotateY(-12deg) scaleX(0.96);
  }
  .book-cell .book-scene:hover .b-page:nth-child(1) { transform: translateX(3px); }
  .book-cell .book-scene:hover .b-page:nth-child(2) { transform: translateX(1.5px); }
}

/* the book whose window is open stays lifted */
.book-cell.is-open .b-image {
  transform: perspective(2000px) translateX(-5px) rotateY(-12deg) scaleX(0.96);
  box-shadow:
    10px 10px 20px rgb(0 0 0 / 0.25),
    20px 20px 40px rgb(0 0 0 / 0.2),
    40px 40px 60px rgb(0 0 0 / 0.15);
}

.shelf-empty {
  grid-column: 1 / -1;
  padding: 48px 0;
  color: var(--ink-soft);
  font-style: italic;
}

/* ---------- stars ---------- */

/* two stacked rows of glyphs; the filled row is clipped to the rating,
   which gives exact halves without half-star glyphs */
.stars {
  position: relative;
  display: inline-block;
  color: var(--ink-faint);
  letter-spacing: 1px;
  line-height: 1;
  white-space: nowrap;
}

.stars::before { content: "★★★★★"; }

.stars .stars-fill {
  position: absolute;
  inset: 0;
  width: var(--fill, 0%);
  overflow: hidden;
  color: var(--ink);
}

.stars .stars-fill::before { content: "★★★★★"; }

/* ---------- book windows ----------------------------------
   Same floating card as the press clippings: striped offset
   shadow behind a solid face, draggable, several at a time.
   ---------------------------------------------------------- */

.book-window {
  --stripe-offset: 6px;
  position: fixed;
  width: min(560px, 92vw);
  padding: 28px;
  overflow: visible;
  isolation: isolate;
  cursor: default;
}

.book-window.is-dragging { cursor: grabbing; user-select: none; }
.book-window.is-dragging * { cursor: grabbing !important; }

.book-window::before {
  content: "";
  position: absolute;
  z-index: 0;
  top: var(--stripe-offset);
  left: var(--stripe-offset);
  width: 100%;
  height: 100%;
  background: repeating-linear-gradient(-45deg, var(--ink) 0 1.5px, transparent 1.5px 4px);
  pointer-events: none;
}

.book-window::after {
  content: "";
  position: absolute;
  z-index: 1;
  inset: 0;
  background: #fff;
  border: 1px solid var(--ink);
  pointer-events: none;
}

.book-window > * { position: relative; z-index: 2; }

.bw-body { display: flex; gap: 24px; align-items: flex-start; }

.bw-cover {
  flex: 0 0 132px;
  width: 132px;
  aspect-ratio: 2 / 3;
  /* there is no .b-image wrapper in here, so this box is what a
     typographic jacket sizes its text against */
  container-type: inline-size;
  box-shadow: 0 2px 6px rgb(0 0 0 / 0.16), 0 8px 18px rgb(0 0 0 / 0.1);
}

.bw-cover img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* keep the fallback's own flex layout — only give it the box's size */
.bw-cover .cover-fallback { width: 100%; height: 100%; }

.bw-main { flex: 1; min-width: 0; }

.bw-author { display: block; color: var(--ink-soft); }

.bw-title {
  font-size: 22px;
  font-weight: 400;
  line-height: 1.25;
  margin: 2px 0 10px;
  text-wrap: balance;
}

.bw-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 12px;
  padding-bottom: 16px;
  margin-bottom: 16px;
  border-bottom: 1px solid var(--rule);
  font-size: 15px;
  color: var(--ink-soft);
}

.bw-notes { text-wrap: pretty; }
.bw-notes p + p { margin-top: 12px; }
.bw-notes:empty::before { content: "No notes on this one."; color: var(--ink-soft); font-style: italic; }

/* window controls: square, cornered, borrowed from the press windows */

.bw-nav {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 3;
  display: flex;
}

.bw-actions {
  position: absolute;
  top: 0;
  right: 0;
  z-index: 3;
  display: flex;
}

.win-btn {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  padding: 0;
  appearance: none;
  background: #fff;
  border: 1px solid var(--ink);
  color: var(--ink);
  cursor: pointer;
}

/* collapse the shared edge between adjacent controls */
.bw-nav .win-btn + .win-btn,
.bw-actions .win-btn + .win-btn { margin-left: -1px; }

.win-btn:disabled { color: var(--ink-faint); cursor: default; }
.win-btn:focus { outline: none; }
.win-btn svg { display: block; }

.win-btn.is-done { background: var(--ink); color: #fff; }

/* ---------- back to top ---------- */

.scroll-top {
  position: fixed;
  right: 24px;
  bottom: 24px;
  z-index: 40;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  padding: 0;
  appearance: none;
  background: var(--paper);
  border: 1px solid var(--ink);
  color: var(--ink);
  cursor: pointer;
  opacity: 0;
  transition: opacity 200ms ease;
}

.scroll-top.is-visible { opacity: 1; }
.scroll-top svg { display: block; }

/* ---------- narrow screens ---------- */

@media (max-width: 1000px) {
  .filters { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px 32px; }
}

@media (max-width: 860px) {
  /* one sheet at a time, centred, scrolling inside itself */
  .book-window {
    left: 12px !important;
    right: 12px !important;
    top: 50% !important;
    bottom: auto !important;
    width: auto !important;
    max-width: none !important;
    max-height: calc(100dvh - 24px) !important;
    transform: translateY(-50%) !important;
    display: flex;
    flex-direction: column;
    padding: 20px;
  }

  .bw-body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    /* the controls sit in the corners; keep content clear of them */
    padding-top: 24px;
  }

  .bw-cover { flex-basis: 96px; width: 96px; }
  .win-btn { width: 36px; height: 36px; }
}

@media (max-width: 600px) {
  body { padding: 44px 20px 0; }

  .filters {
    grid-template-columns: 1fr;
    gap: 0;
    margin-bottom: 40px;
  }

  /* each filter becomes a real disclosure so the shelf stays near the top */
  .filter-block { border-bottom: 1px solid var(--rule); }
  .filter-block > summary { cursor: pointer; padding: 10px 0; pointer-events: auto; }
  .filter-head { display: inline; border: 0; padding: 0; margin: 0; }
  .filter-block > summary::after { content: " +"; color: var(--ink-soft); }
  .filter-block[open] > summary::after { content: " \2212"; }
  .filter-block .link-list { padding: 0 0 12px; }
  .filter-genres .link-list { max-height: none; }

  .shelf { gap: 28px 16px; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); }

  /* on a phone the sheet fills the width — a small cover wastes it */
  .bw-body { display: block; padding-top: 28px; }
  .bw-cover { width: 108px; margin-bottom: 16px; }
}

/* the body sheet must not scroll behind an open window */
body.window-open { overflow: hidden; }
