/* Photography: hardcover photo books, and the viewer they open.
   Each book takes its cover colour from its album; the paper stays neutral. */

/* ---------- the books on the page ---------- */
.book-shelf { --design: 490; --ratio: 52 / 45; }
/* the phone canvas never grows past a phone's width, so the books do not balloon on a small tablet */
@media (max-width: 767px) { .book-shelf { --design: 368; --ratio: 20 / 23; max-width: 26rem; } }

.book-vol { cursor: pointer; transition: transform .3s ease; }
.is-dragging .book-vol { cursor: grabbing; }

/* covers, after real photo books: a solid colour, small type at the head and foot,
   and one small tipped-in photo. The colour and ink come from the album's jacket in data.js. */
.book-board { --mat: var(--book-cover, var(--m-light)); color: var(--book-ink, #161616); }
.book-cover { position: absolute; inset: 0; font-size: calc(var(--u) * 11.5); line-height: 1.15; }
.book-cover-title { text-transform: uppercase; letter-spacing: .04em; }
.book-cover-photo { position: absolute; height: auto; box-shadow: 0 0 0 .5px rgba(0, 0, 0, .3); }

/* plain: title and name in one line at the head, a line at the foot, photo (if any) small in the middle */
.book-cover--plain .book-cover-head {
  position: absolute; left: 0; right: 0; top: calc(var(--u) * 16);
  display: flex; justify-content: center; gap: calc(var(--u) * 14);
}
.book-cover--plain .book-cover-foot { position: absolute; left: 0; right: 0; bottom: calc(var(--u) * 15); text-align: center; }
.book-cover--plain .book-cover-photo { left: 50%; top: 50%; width: calc(var(--u) * 70); transform: translate(-50%, -50%); }

/* tipped: title top left, photo tipped in top right, two lines bottom left */
.book-cover--tipped { font-size: calc(var(--u) * 15); }
.book-cover--tipped .book-cover-head { position: absolute; left: calc(var(--u) * 20); top: calc(var(--u) * 18); }
.book-cover--tipped .book-cover-name { display: none; }
.book-cover--tipped .book-cover-photo { right: calc(var(--u) * 14); top: calc(var(--u) * 14); width: calc(var(--u) * 96); }
.book-cover--tipped .book-cover-foot {
  position: absolute; left: calc(var(--u) * 20); bottom: calc(var(--u) * 18); width: calc(var(--u) * 110);
}
/* the spine reads top to bottom: title at the head, his name at the foot */
.book-spine { position: absolute; inset: 0; font-size: calc(var(--u) * 11); }
.book-spine span {
  position: absolute; left: 0; width: 100%;
  writing-mode: vertical-rl; white-space: nowrap; line-height: calc(var(--u) * var(--book-d, 32));
}
.book-spine-title { top: calc(var(--u) * 18); text-transform: uppercase; letter-spacing: .04em; }
.book-spine-name { bottom: calc(var(--u) * 18); }
/* the fore-edge: a very faint line for every few sheets */
.book-edge { background-image: repeating-linear-gradient(to right, rgba(0, 0, 0, 0) 0 calc(var(--u) * 1.6), rgba(0, 0, 0, .07) calc(var(--u) * 1.6) calc(var(--u) * 2.2)); }

/* The caption, on the same grid as the About list: a hairline above every row, the title in the
   left column, the description beside it, the way in at the far right. On a phone the description
   drops under the title. */
.book-list { display: grid; }
.book-row {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "title act" "info info";
  column-gap: var(--s-16); row-gap: var(--s-8); align-items: start;
  padding: var(--s-16) 0; border-top: 1px solid var(--line);
}
.book-row:last-child { border-bottom: 1px solid var(--line); }
.book-row-title { grid-area: title; }
.book-row-info { grid-area: info; }
/* the control's hit area is taller than a line of type: pull it back so its text sits on the row's first line */
.book-row > .act { grid-area: act; margin-block: calc((var(--lh) - var(--s-48)) / 2); }
@media (min-width: 768px) {
  .book-row { grid-template-columns: var(--col-label) minmax(0, 1fr) auto; grid-template-areas: "title info act"; }
}

/* ---------- the viewer ---------- */
.book-dialog {
  position: fixed; inset: 0; width: 100%; height: 100%; height: 100dvh;
  max-width: none; max-height: none; margin: 0; border: 0; overflow: hidden;
  padding: env(safe-area-inset-top, 0px) env(safe-area-inset-right, 0px) env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);
  background: var(--bg); color: var(--ink);
}
.book-dialog[open] { display: flex; flex-direction: column; }
.book-dialog::backdrop { background: var(--bg); }
/* While the content note shows, the dialog itself scrolls, so the keyboard can scroll the note
   from the title. The bar stays in reach. */
.book-dialog--note { overflow-y: auto; }
.book-dialog--note .book-bar { position: sticky; top: 0; z-index: 1; background: var(--bg); }

/* the bar: on a phone the title, [Grid] and Close share the first row and the page controls take the second;
   from 600px everything sits in one row */
.book-bar {
  display: grid; grid-template-columns: minmax(0, 1fr) auto auto; grid-template-areas: "title mode close" "nav nav nav";
  align-items: center; column-gap: var(--s-16);
  padding: var(--s-8) var(--gutter);
}
.book-title { grid-area: title; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.book-nav { grid-area: nav; justify-content: space-between; }
.book-mode { grid-area: mode; }
.book-close { grid-area: close; }
.book-pos { text-align: center; white-space: nowrap; font-variant-numeric: tabular-nums; color: var(--ink-2); }
.book-pos:empty { display: none; }
/* a phone has room for "3 of 26"; the word before it is still read out */
.book-pos-word { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

.book-view {
  flex: 1; min-height: 0; container-type: size; margin-bottom: var(--gutter);
  display: grid; place-items: center;
  touch-action: pan-y pinch-zoom;
}
/* The stage is as large as the space allows, whichever of width and height runs out first.
   It keeps headroom above the book for the turning leaf; when there is height to spare it moves up
   by half of that, so the book and not its headroom sits in the middle. */
.book-open {
  --book-w: min(100cqw, calc(100cqh * var(--book-fit, 1.5)));
  width: var(--book-w);
  margin-top: calc(-2 * min((100cqh - var(--book-w) / var(--book-fit, 1.5)) / 2, var(--book-w) * var(--book-lift, 0)));
  cursor: auto; touch-action: pan-y pinch-zoom;
}
/* from 600px the title and the controls share one row, and the position is spelled out */
@media (min-width: 600px) {
  .book-bar { grid-template-columns: minmax(0, 1fr) auto auto auto; grid-template-areas: "title nav mode close"; column-gap: var(--s-24); }
  .book-nav { justify-content: flex-start; }
  .book-pos { min-width: 12rem; }
  .book-pos-word { position: static; width: auto; height: auto; overflow: visible; clip-path: none; }
}
@media (min-width: 768px) {
  .book-view { margin-inline: var(--gutter); }
}

/* pages */
/* the turning leaf: a chain of strips, moved by the script frame by frame (see bend in books.js) */
.book-leaf { pointer-events: none; }
.book-leaf-face { overflow: hidden; }
.book-slice {
  position: absolute; top: 0; height: 100%;
  /* + 0.3: each strip is drawn 0.6 wider than its share, half of it before its hinge; this lines the photo up with the page's */
  left: calc(var(--u) * (var(--book-at, 0) + 0.3)); width: calc(var(--u) * var(--book-pw, 360));
}
.book-slice-photo {
  position: absolute; inset: calc(var(--u) * var(--book-margin, 20));
  background: center / contain no-repeat;
}
/* the strips nearest the spine keep the gutter shadow the pages at rest have, so nothing flashes as a turn starts */
.book-slice::before { content: ""; position: absolute; top: 0; bottom: 0; width: calc(var(--u) * 30); pointer-events: none; }
.book-slice--right::before { left: 0; background: linear-gradient(to right, rgba(0, 0, 0, .16), rgba(0, 0, 0, .04) 45%, rgba(0, 0, 0, 0)); }
.book-slice--left::before { right: 0; background: linear-gradient(to left, rgba(0, 0, 0, .16), rgba(0, 0, 0, .04) 45%, rgba(0, 0, 0, 0)); }
.book-spread--dark .book-slice--right::before { background: linear-gradient(to right, #000, rgba(0, 0, 0, 0)); }
.book-spread--dark .book-slice--left::before { background: linear-gradient(to left, #000, rgba(0, 0, 0, 0)); }
/* no edge line between one strip and the next */
.book-strip .face { box-shadow: none; }
.book-page { position: absolute; inset: calc(var(--u) * var(--book-margin, 20)); }
.book-photo { width: 100%; height: 100%; object-fit: contain; font-size: calc(var(--u) * 12); }
/* the gutter: both pages fall away into the spine */
.book-face::before {
  content: ""; position: absolute; top: 0; bottom: 0; width: calc(var(--u) * 30); pointer-events: none;
}
.book-face--left::before { right: 0; background: linear-gradient(to left, rgba(0, 0, 0, .16), rgba(0, 0, 0, .04) 45%, rgba(0, 0, 0, 0)); }
.book-face--right::before { left: 0; background: linear-gradient(to right, rgba(0, 0, 0, .16), rgba(0, 0, 0, .04) 45%, rgba(0, 0, 0, 0)); }
.book-spread--dark .book-face--left::before { background: linear-gradient(to left, #000, rgba(0, 0, 0, 0)); }
.book-spread--dark .book-face--right::before { background: linear-gradient(to right, #000, rgba(0, 0, 0, 0)); }

/* the soft shadow the open book casts on the table */
.book-shadow > .face {
  background: rgba(0, 0, 0, .2); box-shadow: none;
  border-radius: calc(var(--u) * 8); filter: blur(calc(var(--u) * 12));
}

/* The grid: every photo at once, uncropped, each sitting on the foot of its cell with its number under it,
   so the pictures share a baseline row by row. One gap, the gutter, between cells both ways. */
.book-grid { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: var(--s-8) var(--gutter) var(--s-48); }
.book-cells { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--gutter); }
@media (min-width: 600px) { .book-cells { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .book-cells { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (min-width: 1440px) { .book-cells { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
.book-cell {
  appearance: none; border: 0; margin: 0; padding: 0; background: none; color: inherit; font: inherit;
  display: grid; gap: var(--s-8); width: 100%; text-align: left; cursor: pointer;
}
.book-cell-frame { display: block; aspect-ratio: 4 / 5; }
.book-cell img { width: 100%; height: 100%; object-fit: contain; object-position: left bottom; }
.book-cell-no { font-size: var(--fs-label); line-height: var(--lh-label); font-variant-numeric: tabular-nums; }
.book-cell:hover .book-cell-no { text-decoration: underline; text-underline-offset: .18em; }

/* the content note */
.book-gate { flex: none; padding: var(--s-24) var(--gutter) var(--s-48); }
.book-gate > * { max-width: 34em; }
/* one clear line between the heading, the text, the two choices and the note */
.book-gate h3 { margin-bottom: var(--s-24); }
.book-gate > .acts { margin-top: var(--s-24); }
/* the note is always shown: a hairline, a tiny label, then his words */
.book-note { margin-top: var(--s-48); padding-top: var(--s-16); border-top: 1px solid var(--line); }
.book-note .prose { padding-top: var(--s-24); }

@media (forced-colors: active) {
  .book-shadow { display: none; }
}
