/* ================= Library: shelves of spines ================= */
/* A page of sections (a month, a century, a genre), each a header that pins under the bars while its books pass and is
   pushed off by the next, then rows of books on ledges. Essential reading is bound in black, the rest in cream; the
   genre is the band at the foot. */
body[data-view="library"] { background: var(--wall); }
.library {
  --row: 252px; --stick: 112px;
  max-width: 1240px; margin: 0 auto; padding: 0 clamp(16px, 4vw, 48px) 120px;
}
@media (min-width: 1100px) { .library { max-width: calc(1240px + 84px); padding-right: calc(clamp(16px, 4vw, 48px) + 84px); } }
@media (max-width: 639px) { .library { --row: 222px; } }

.pin-mark { position: absolute; top: 0; left: 0; width: 1px; height: 1px; pointer-events: none; }
.month { position: relative; min-width: 0; scroll-margin-top: var(--stick); content-visibility: auto; contain-intrinsic-size: auto 340px; }
.month-head {
  position: sticky; top: var(--stick); z-index: 12; height: 76px; display: flex; align-items: flex-end; gap: 14px;
  margin: 0; padding: 0 2px 10px; background: var(--wall);
}
.month-head::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px; background: var(--rule); opacity: 0; transition: opacity .3s; }
/* the books passing under a pinned header fade into it rather than being cut off at a line */
.month-head::before { content: ""; position: absolute; left: 0; right: 0; top: 100%; height: 22px; background: linear-gradient(var(--wall), transparent); opacity: 0; transition: opacity .3s; pointer-events: none; }
.month-head h2 { display: block; margin: 0; font: 400 clamp(36px, 3.4vw, 44px)/1 var(--font-display); letter-spacing: -.005em; white-space: nowrap;
  transform-origin: 0 100%; transition: transform .35s cubic-bezier(.2,.8,.2,1); }
.month-head .m { display: flex; align-items: center; gap: 8px; min-width: 0; padding-bottom: 6px; transition: transform .35s cubic-bezier(.2,.8,.2,1); }
.month-head .sw { flex: none; width: 9px; height: 9px; border-radius: 2px; background: var(--g); }
.month-head p { margin: 0; font: 500 10.5px/1.4 var(--font-ui); letter-spacing: .16em; text-transform: uppercase; color: var(--ink-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.month-head .now { color: var(--ink); }
/* pinned: the title settles to a smaller size on the same baseline, the line beside it follows, a hairline under */
.month-head.pinned h2 { transform: scale(.62); }
.month-head.pinned .m { transform: translateX(calc(var(--shrink, 0px) * -1)); }
.month-head.pinned::after, .month-head.pinned::before { opacity: 1; }
@media (max-width: 639px) { .month-head { height: 64px; } .month-head h2 { font-size: 32px; } }

/* rows of books on ledges: every book the same height, a ledge under each row */
.shelf-rows {
  display: flex; flex-wrap: wrap; align-items: flex-end; align-content: flex-start; gap: 0 2px; padding: 18px 10px 30px;
  background: repeating-linear-gradient(to bottom, transparent 0 calc(var(--row) - 14px), var(--ledge-edge) calc(var(--row) - 14px) calc(var(--row) - 12px), var(--ledge) calc(var(--row) - 12px) var(--row));
}

/* ================= A book on the shelf: flat at rest, a box when pointed at ================= */
/* At rest a book is its spine with a thin strip of page edge above it, so hundreds of books cost no 3D layers;
   pointed at, found or taken out it becomes a box (the same faces the pulled-out book is made of). */
.book {
  --c: #7a3b2e; --a: #d9b45a; --g: #8a8a83;
  position: relative; flex: 0 0 auto; width: var(--t); height: var(--h); margin: calc(var(--row) - var(--h) - 14px) 0 14px;
  padding: 0; border: 0; background: none; cursor: pointer; -webkit-tap-highlight-color: transparent; transition: opacity .3s ease;
}
.book::before { content: ""; position: absolute; left: 0; right: 0; top: -5px; height: 5px; clip-path: polygon(6% 0, 94% 0, 100% 100%, 0 100%);
  background: linear-gradient(90deg, rgb(0 0 0 / .12), transparent 18%, transparent 82%, rgb(0 0 0 / .12)), repeating-linear-gradient(90deg, #f2ede1 0 1px, #e3dccb 1px 2px); }
.book::after { content: ""; position: absolute; left: -1px; right: -3px; bottom: -3px; height: 5px; background: radial-gradient(closest-side, rgb(0 0 0 / .2), transparent); pointer-events: none; }
.book .book-3d { transform: none; transition: transform .3s cubic-bezier(.2,.8,.2,1); }
.book.arming .book-3d { transition: none; } /* flat to box in one frame: the box at rest looks the same */
.book .face.spine { transform: none; }
.book .face.top, .book .face.cover { display: none; }
.book.live { perspective: 1400px; perspective-origin: 50% -30%; z-index: 2; }
.book.live::before { display: none; }
.book.live .book-3d { transform-style: preserve-3d; transform: translateZ(calc(var(--w) / -2)); }
.book.live .face.spine { transform: translateZ(calc(var(--w) / 2)); }
.book.live .face.top, .book.live .face.cover { display: block; }
.book.live.up .book-3d, .book.live.hit .book-3d { transform: translateZ(calc(var(--w) / -2 + 30px)) translateY(-8px) rotateY(-18deg); }
.book.is-out .book-3d { opacity: 0; transition: none; }
.book.is-out::before, .book.is-out::after { opacity: 0; }
.book:focus-visible { outline: none; }
.book:focus-visible .spine { outline: 2px solid var(--focus); outline-offset: 2px; }
.library.searching .book:not(.match) { opacity: .22; }
.book[data-status="planned"] { cursor: default; }
.book[data-status="planned"] .spine { opacity: .5; }

/* ================= Book (3D): the faces, on the shelf and pulled out ================= */
.book-3d {
  position: absolute; inset: 0; transform-style: preserve-3d;
  transform: translateZ(calc(var(--w) / -2));
}
.face { position: absolute; display: block; backface-visibility: hidden; -webkit-backface-visibility: hidden; }
/* the spine: cream paper (black for essential reading), the title in a serif, the author's surname in small capitals,
   a hairline, the genre band, the library's mark */
.spine {
  left: 0; top: 0; width: var(--t); height: var(--h); box-sizing: border-box; overflow: hidden;
  transform: translateZ(calc(var(--w) / 2));
  display: flex; flex-direction: column; align-items: center;
  background: var(--spine-cream); color: var(--spine-ink);
}
.spine::after { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(90deg, rgb(0 0 0 / .16), rgb(0 0 0 / .02) 14%, rgb(255 255 255 / .07) 34%, transparent 56%, rgb(0 0 0 / .04) 82%, rgb(0 0 0 / .18)); }
.spine .sp-t { flex: 1; min-height: 0; padding: 13px 0 6px; display: flex; justify-content: center; }
.spine .sp-t span { writing-mode: vertical-rl; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-height: 100%;
  font: 500 var(--fs, 14px)/1 var(--font-display); }
.spine .sp-v { font: 500 10px/1 var(--font-display); margin-bottom: 6px; color: var(--spine-ink-2); }
.spine .sp-a { font: 600 6.5px/1 var(--font-ui); letter-spacing: .14em; writing-mode: vertical-rl; text-transform: uppercase; color: var(--spine-ink-2);
  max-height: 56px; overflow: hidden; margin-bottom: 8px; }
.spine .sp-l { flex: 0 0 1px; width: 100%; background: rgb(0 0 0 / .12); }
.spine .sp-g { flex: 0 0 5%; width: 100%; background: var(--g); }
.spine .sp-m { flex: 0 0 22px; display: grid; place-items: center; }
.spine .sp-m svg { width: 10px; height: 10px; }
.spine.must { background: var(--spine-black); color: var(--spine-cream-ink); }
.spine.must .sp-v, .spine.must .sp-a { color: rgb(239 232 216 / .72); }
.spine.must .sp-l { background: rgb(239 232 216 / .5); }
.cover, .back {
  top: 0; width: var(--w); height: var(--h);
  left: calc((var(--t) - var(--w)) / 2);
  background: var(--spine-cream);
}
.must .cover, .must .back { background: var(--spine-black); }
.cover { transform: rotateY(90deg) translateZ(calc(var(--t) / 2)); }
.back  { transform: rotateY(-90deg) translateZ(calc(var(--t) / 2)); filter: brightness(.8); }
.top {
  left: 0; width: var(--t); height: var(--w);
  top: calc((var(--h) - var(--w)) / 2);
  transform: rotateX(90deg) translateZ(calc(var(--h) / 2));
  background: linear-gradient(90deg, rgb(0 0 0 / .12), transparent 18%, transparent 82%, rgb(0 0 0 / .12)), repeating-linear-gradient(90deg, #f2ede1 0 1px, #e3dccb 1px 2px);
}
/* ================= Cover art: the same paper as the spine, title, author, the genre band, the mark ================= */
.cover-art {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  background: var(--spine-cream); color: var(--spine-ink);
}
.must .cover-art, .cover-art.must { background: var(--spine-black); color: var(--spine-cream-ink); }
.cover-art .ca-t { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8%; padding: 12% 10%; text-align: center; }
.cover-art .ca-t svg { width: 34%; height: auto; opacity: .85; }
.cover-art .ca-t b { font: 500 calc(var(--w) * .115)/1.12 var(--font-display); text-wrap: balance; }
.cover-art .ca-t i { font: 600 calc(var(--w) * .042)/1.4 var(--font-ui); font-style: normal; letter-spacing: .16em; text-transform: uppercase; opacity: .72; }
.cover-art .ca-g { flex: 0 0 6%; background: var(--g); }
.cover-art .ca-m { flex: 0 0 13%; display: grid; place-items: center; }
.cover-art .ca-m svg { width: 9%; height: auto; }

/* ================= Pull-out layer ================= */
#flight-layer {
  position: fixed; inset: 0; z-index: 40; pointer-events: none;
  perspective: 2200px; perspective-origin: 50% 45%;
}
#flight-layer.active { pointer-events: auto; }
.flight-backdrop {
  position: absolute; inset: 0;
  background: var(--scrim);
  opacity: 0; transition: opacity .5s ease;
}
#flight-layer.active .flight-backdrop { opacity: 1; }
.frig { position: absolute; inset: 0; perspective: 2200px; perspective-origin: 50% 45%; transform-origin: 0 0; pointer-events: none; }
.frig .fbook { pointer-events: auto; }
.fbook {
  position: absolute; transform-style: preserve-3d;
  width: var(--t); height: var(--h);
  transform-origin: 50% 50% calc(var(--w) / -2);
}
.fbook .book-3d { transition: none; }
.fbook .cover { transform-style: preserve-3d; background: transparent; }
.cover-board { position: absolute; inset: 0; transform-style: preserve-3d; transform-origin: 0 50%; }
.cover-board .cover-art, .cover-board .endpaper { backface-visibility: hidden; -webkit-backface-visibility: hidden; }
.endpaper {
  position: absolute; inset: 0; transform: rotateY(180deg);
  background: color-mix(in srgb, var(--g) 22%, var(--surface));
}
/* the pulled-out book is flat, like its cover: no leather, no gilt bands */
.fbook .spine .sp-t span { font-size: calc(var(--t) * .42); }
.title-page {
  position: absolute; inset: 1.5% 1.5% 1.5% 0; transform: translateZ(-2px);
  background: linear-gradient(90deg, color-mix(in srgb, var(--page) 88%, #000), var(--page) 7%);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6%;
  color: var(--page-ink); text-align: center; padding: 12%;
}
.title-page .tt { font: 500 calc(var(--w) * .11)/1.15 var(--font-display); }
.title-page .tv { font: 500 calc(var(--w) * .05)/1.2 var(--font-ui); letter-spacing: .16em; text-transform: uppercase; color: var(--page-ink-2); }
.title-page .ta { font: 500 calc(var(--w) * .045)/1.2 var(--font-ui); letter-spacing: .16em; text-transform: uppercase; color: var(--page-ink-2); }
.tp-wash { position: absolute; inset: 0; background: var(--page); opacity: 0; }
.title-page hr { width: 18%; border: 0; border-top: 1px solid var(--page-ink-2); margin: 0; opacity: .5; }

.flight-info {
  position: absolute; width: min(340px, calc(100vw - 32px));
  color: var(--ink);
  opacity: 0; transform: translateY(10px); transition: opacity .35s ease, transform .35s ease;
}
#flight-layer.show-info .flight-info { opacity: 1; transform: none; }
.flight-info h2 { margin: 0 0 8px; font: 400 clamp(34px, 4.4vw, 48px)/1.02 var(--font-display); letter-spacing: -.005em; text-wrap: balance; }
.flight-info .vol { margin: 0 0 6px; font: 500 13px/1.3 var(--font-ui); letter-spacing: .12em; text-transform: uppercase; color: var(--ink-2); }
.flight-info .by { margin: 0 0 18px; font: 500 11px/1.4 var(--font-ui); letter-spacing: .16em; text-transform: uppercase; color: var(--ink-3); }
.flight-info dl { display: grid; grid-template-columns: auto 1fr; gap: 6px 16px; margin: 0 0 22px; font-size: 14px; }
.flight-info dt { color: var(--ink-3); font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase; align-self: baseline; }
.flight-info dd { margin: 0; }
.flight-info .meter { height: 3px; border-radius: 2px; background: var(--rule); overflow: hidden; margin-top: 7px; }
.flight-info .meter i { display: block; height: 100%; background: var(--accent); }
.flight-info .actions { display: flex; gap: 10px; flex-wrap: wrap; }
.flight-info .btn.ghost { color: var(--ink); border-color: var(--rule); }
.fi-links { margin: -4px 0 20px; }
.fi-links h3 { margin: 0 0 6px; font: 500 12px/1.3 var(--font-ui); letter-spacing: .12em; text-transform: uppercase; color: var(--ink-3); }
.fi-links ul { list-style: none; margin: 0; padding: 0; max-height: min(30vh, 200px); overflow-y: auto; }
@media (max-width: 759px) { .fi-links ul { max-height: min(15vh, 124px); } } /* phones: Read stays on screen under a long list */
.fi-links button {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px; width: 100%;
  padding: 6px 0; border: 0; border-bottom: 1px solid var(--rule); background: none; color: var(--ink);
  font: inherit; text-align: left; cursor: pointer;
}
.fi-links li:last-child button { border-bottom: 0; }
.fi-links .t { font: 500 17px/1.25 var(--font-display); }
.fi-links .k { flex: none; font-size: 12.5px; color: var(--ink-3); }
.fi-links button:hover .t, .fi-links button:focus-visible .t { text-decoration: underline; text-underline-offset: 3px; }
.flight-close {
  position: absolute; top: max(12px, env(safe-area-inset-top)); right: 12px;
  width: 44px; height: 44px; border-radius: 50%; border: 0; cursor: pointer;
  background: var(--surface); color: var(--ink); box-shadow: var(--shadow); display: grid; place-items: center;
  opacity: 0; transition: opacity .3s;
}
#flight-layer.show-info .flight-close { opacity: 1; }
.flight-close svg { width: 20px; height: 20px; }


/* ================= Timeline (right edge) ================= */
.month-nav {
  position: fixed; right: max(16px, env(safe-area-inset-right)); top: calc(50% + 28px); transform: translateY(-50%); z-index: 20;
  display: flex; flex-direction: column; align-items: flex-end; gap: 1px;
  max-height: calc(100dvh - 140px); overflow-y: auto; scrollbar-width: none; padding: 4px 0;
}
.month-nav::-webkit-scrollbar { display: none; }
.month-nav a {
  display: block; padding: 4px 8px; border-radius: 6px; text-decoration: none; text-align: right;
  font-size: 12.5px; line-height: 1.25; color: var(--ink-3); font-variant-numeric: tabular-nums;
}
.month-nav a:hover { color: var(--ink); }
.month-nav a[aria-current="true"] { color: var(--ink); font-weight: 600; }
.timeline .tl-year { display: flex; flex-direction: column; align-items: flex-end; position: relative; padding-right: 10px; }
.timeline .tl-year::before { /* the year's rail */
  content: ""; position: absolute; right: 0; top: 8px; bottom: 8px; width: 2px; border-radius: 1px; background: var(--rule);
  transition: background .3s;
}
.timeline .tl-year.open::before { background: var(--ink-3); }
.timeline .tl-y { font-weight: 600; font-size: 13px; color: var(--ink-2); padding: 6px 8px; }
.timeline .tl-year.open .tl-y { color: var(--ink); }
.timeline .tl-months { overflow: hidden; display: flex; flex-direction: column; align-items: flex-end; max-height: 0; transition: max-height .35s cubic-bezier(.3,.8,.3,1); }
.timeline .tl-year.open .tl-months { max-height: 340px; }
.timeline .tl-months a { padding: 2px 8px; font-size: 12px; }
.timeline .tl-months a[aria-current="true"] { position: relative; }
.timeline .tl-months a[aria-current="true"]::after { /* marker on the rail */
  content: ""; position: absolute; right: -14px; top: 50%; width: 6px; height: 6px; margin-top: -3px; border-radius: 50%;
  background: var(--ink); box-shadow: 0 0 0 3px var(--wall);
}
@media (max-width: 1099px) { .month-nav { display: none; } }

/* ================= Arrange + tags ================= */
.topbar-title .arrange { display: inline-grid; grid-auto-flow: column; gap: 0; padding: 2px; border: 1px solid var(--rule); border-radius: 999px; background: color-mix(in srgb, var(--surface) 70%, transparent); }
.arrange .chip { border: 0; min-height: 32px; padding: 0 14px; font: 500 13.5px/1 var(--font-ui); }
.arrange .chip[aria-pressed="true"] { background: var(--ink); color: var(--wall); }
/* tags: one row that scrolls sideways, held under the top bar */
.tagbar {
  grid-column: 1 / -1; position: sticky; top: 56px; z-index: 15;
  margin: 0 calc(-1 * clamp(16px, 4vw, 48px)); padding: 10px clamp(16px, 4vw, 48px);
  background: color-mix(in srgb, var(--wall) 82%, transparent);
  backdrop-filter: blur(12px) saturate(1.2); -webkit-backdrop-filter: blur(12px) saturate(1.2);
}
.tag-track {
  display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; overscroll-behavior-x: contain;
  -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 40px), transparent);
  mask-image: linear-gradient(90deg, #000 calc(100% - 40px), transparent);
  padding-right: 40px;
}
.tag-track::-webkit-scrollbar { display: none; }
.tagbar .chip { flex: 0 0 auto; min-height: 32px; font-size: 13px; background: color-mix(in srgb, var(--surface) 55%, transparent); }
.tagbar .chip[aria-pressed="true"] { background: var(--ink); }
.book.dim { opacity: .12; pointer-events: none; }

/* ================= Search on the shelves ================= */
.shelf-search { position: relative; flex: none; display: block; }
.shelf-search input { width: min(260px, 46vw); height: 34px; box-sizing: border-box; border: 1px solid var(--rule); border-radius: 999px;
  background: var(--surface); color: var(--ink); font: 14px var(--font-ui); padding: 0 60px 0 34px; }
.shelf-search input::-webkit-search-cancel-button { display: none; }
.shelf-search svg { position: absolute; left: 12px; top: 9px; width: 16px; height: 16px; color: var(--ink-3); pointer-events: none; }
.shelf-search .n { position: absolute; right: 12px; top: 8px; font-size: 12px; color: var(--ink-3); font-variant-numeric: tabular-nums; pointer-events: none; }
.tagbar { display: flex; align-items: center; gap: 10px; }
.tagbar .tag-track { flex: 1; min-width: 0; }
@media (max-width: 560px) { .arrange .chip { padding: 0 11px; } }
/* in the air between shelves and map the lettering fades (transit.js); the spine keeps its paper and its band */
.fly .spine::after { display: none; }
.fly .spine > :not(.sp-g) { visibility: hidden; } /* only paper and band in the air: lettering would be painted again every frame */
