/* Library — benolivas.com/library/
   One stylesheet for the grid and every book page.
   No external requests: system fonts only. */

:root {
  --paper: #fafaf8;
  --ink: #000;
  --mute: #767676;          /* 4.5:1 on --paper */
  --rule: 1px solid var(--ink);
  --pad: 16px;
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 15px/1.4 "Helvetica Neue", Helvetica, Arial, sans-serif;
}
a { color: inherit; text-decoration: none; }
:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
img { display: block; max-width: 100%; height: auto; }

.site { max-width: 1600px; margin: 0 auto; padding: var(--pad); }

/* ---- Header ---------------------------------------------------------- */
.top { margin: 0 0 24px; }
.top p { margin: 0; }
.top a { text-decoration: underline; text-underline-offset: 2px; }
.top a:hover { text-decoration-thickness: 2px; }

/* ---- Grid ------------------------------------------------------------
   Each cell draws a full border and overlaps its neighbours by 1px, so
   shared edges stay 1px and an incomplete last row needs no filler cells. */
.grid {
  list-style: none;
  margin: 0;
  padding: 0 1px 1px 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.cell { border: var(--rule); margin: 0 -1px -1px 0; }
.cell > a {
  display: grid;
  grid-template-rows: auto auto 1fr;
  height: 100%;
  padding: 10px 12px 16px;
}
.cell .yr { font-size: 13px; }
figure { margin: 0; }
.cell .plate {
  /* A square made with padding, not aspect-ratio: Safari mis-sizes children
     that take a percentage of an aspect-ratio box, so the cover sits in an
     absolutely positioned layer instead. Works in every browser back to 1999. */
  display: block;
  position: relative;
  height: 0;
  padding-top: 100%;
}
.cell .plate > img {
  position: absolute;
  top: 10%;
  left: 10%;
  width: 80%;
  height: 80%;
  object-fit: contain;
}
.cell .cap { text-align: center; align-self: end; }
.cell .plate > .ph-cover {
  position: absolute;
  top: 10%;
  left: 20%;
  width: 60%;   /* 60 x 80 of a square = 3:4 */
  height: 80%;
}
.cell .t, .cell .a { display: block; }
.cell .a { font-style: italic; margin-top: 2px; }
.cell > a:hover .t,
.cell > a:focus-visible .t { text-decoration: underline; text-underline-offset: 2px; }

/* ---- Placeholders -----------------------------------------------------
   Anything with .ph is temporary. Search the files for class="ph" to find
   what is left to replace. */
.ph-cover {
  width: 64%;
  max-height: 100%;
  aspect-ratio: 3 / 4;
  border: 1px dashed var(--mute);
  color: var(--mute);
  font-size: 12px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 8px;
  overflow-wrap: anywhere;
}
.ph {
  color: var(--mute);
  border: 1px dashed var(--mute);
  padding: 12px 14px;
}
.ph p { margin: 0 0 .6em; }
.ph p:last-child { margin: 0; }

/* ---- Book page -------------------------------------------------------- */
.book {
  display: grid;
  grid-template-columns: minmax(220px, 300px) minmax(0, 1fr);
  border: var(--rule);
}
.meta { border-right: var(--rule); padding: 12px 14px 20px; }
.meta h1 { font-size: 24px; line-height: 1.15; font-weight: normal; margin: 0; }
.meta .sub { margin: 6px 0 0; }
.meta dl {
  margin: 28px 0 0;
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: 6px 14px;
  font-size: 13px;
}
.meta dt { color: var(--mute); }
.meta dd { margin: 0; }

.main { min-width: 0; }
.main .plate {
  margin: 0;
  position: relative;
  height: min(64vh, 680px);
  border-bottom: var(--rule);
}
.main .plate > img {
  position: absolute;
  top: 7%;
  left: 7%;
  width: 86%;
  height: 86%;
  object-fit: contain;
}
.main .plate > .ph-cover {
  position: absolute;
  top: 7%;
  left: 50%;
  height: 86%;
  width: auto;
  transform: translateX(-50%);
}
.text { padding: 16px 14px 32px; max-width: 40em; }
.text > p { margin: 0 0 1em; }

/* ---- Writing ----------------------------------------------------------
   Everything you can put in a note: links, headings, lists, quotes,
   images, galleries, expandos and embeds. Plain HTML, no script. */
.text a { text-decoration: underline; text-underline-offset: 2px; }
.text a:hover { text-decoration-thickness: 2px; }
.text h2 { font-size: 15px; font-weight: bold; margin: 1.8em 0 .4em; }
.text ul, .text ol { margin: 0 0 1em; padding-left: 1.4em; }
.text li { margin-bottom: .3em; }
.text blockquote { margin: 0 0 1em; padding-left: 14px; border-left: var(--rule); }
.text code, .text pre { font: 13px/1.5 ui-monospace, Menlo, Consolas, monospace; }
.text pre { margin: 0 0 1em; padding: 10px 12px; border: 1px dashed var(--mute); overflow-x: auto; }
.text figure { margin: 1.4em 0; }
.text figcaption { font-size: 13px; color: var(--mute); margin-top: 6px; }
.text .gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 8px;
  align-items: start;
  margin: 1.4em 0;
}

/* Expando, after RES: a closed <details> loads nothing visible until opened. */
.text details { margin: 0 0 1em; }
.text summary { cursor: pointer; list-style: none; text-decoration: underline; text-underline-offset: 2px; }
.text summary::-webkit-details-marker { display: none; }
.text summary::before { content: "[+] "; font-family: ui-monospace, Menlo, Consolas, monospace; text-decoration: none; display: inline-block; white-space: pre; }
.text details[open] summary::before { content: "[\2212] "; }
.text details > :not(summary) { margin-top: 8px; }

.text .embed { aspect-ratio: 16 / 9; border: var(--rule); }
.text .embed iframe { width: 100%; height: 100%; border: 0; display: block; }

/* ---- Video player ------------------------------------------------------
   <figure class="player"> + player.js. Text controls under a 1px frame. */
.player { margin: 1.4em 0; border: var(--rule); }
.player video { display: block; width: 100%; height: auto; background: var(--ink); cursor: pointer; }
.player figcaption { margin: 0; padding: 6px 10px 8px; border-top: var(--rule); }
.controls {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 7px 10px 8px;
  border-top: var(--rule);
  font-size: 13px;
}
.controls button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
  white-space: nowrap;
}
.controls button:hover { text-decoration-thickness: 2px; }
.controls .time { font-family: ui-monospace, Menlo, Consolas, monospace; white-space: nowrap; }
.controls .seek { flex: 1; min-width: 60px; height: 9px; border: var(--rule); cursor: pointer; }
.controls .fill { height: 100%; width: 0; background: var(--ink); }

.pager {
  display: grid;
  grid-template-columns: 1fr 1fr;
  border: var(--rule);
  border-top: 0;
}
.pager a { padding: 10px 14px 12px; }
.pager a + a { border-left: var(--rule); text-align: right; }
.pager span { display: block; }
.pager span:first-child { font-size: 13px; color: var(--mute); }
.pager a:hover .t,
.pager a:focus-visible .t { text-decoration: underline; text-underline-offset: 2px; }

/* ---- Breakpoints -------------------------------------------------------
   Kept last: these share specificity with the rules above and must win. */
@media (min-width: 1200px) {
  .grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (max-width: 699px) {
  :root { --pad: 12px; }
  .grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cell > a { padding: 8px 8px 12px; }
  .cell .yr, .cell .cap { font-size: 13px; }
  .cell .ph-cover span + span { display: none; }
  .book { grid-template-columns: minmax(0, 1fr); }
  .meta { border-right: 0; border-bottom: var(--rule); }
  .main .plate { height: 0; padding-top: 100%; }
  .controls { flex-wrap: wrap; row-gap: 8px; }
  .controls .seek { order: -1; flex-basis: 100%; height: 12px; }
}

/* ─── Arriving from the portfolio ─────────────────────────────
   The other half of this pair is in the portfolio's index.html.
   Both documents must carry the @view-transition opt-in; the
   animation is always styled by the document being ENTERED, so
   these rules run on the way IN here and the portfolio's own
   copy runs on the way back out.

   Unsupported in Firefox, which navigates as before. Nothing to
   fall back to — that is the current behaviour. */
@view-transition { navigation: auto; }

::view-transition-old(root){
  animation: lib-exit 220ms cubic-bezier(.4,0,1,1) both;
}
::view-transition-new(root){
  animation: lib-enter 460ms cubic-bezier(.16,.84,.26,1) 70ms both;
}
@keyframes lib-exit  { to { opacity: 0 } }
@keyframes lib-enter {
  from { opacity: 0; transform: translate3d(0,12px,0) }
  to   { opacity: 1; transform: none }
}

/* The setting asks for no transition, and a crossfade is one.
   Both snapshots then sit at full opacity and the new page is
   simply there. */
@media (prefers-reduced-motion: reduce){
  ::view-transition-old(root),
  ::view-transition-new(root){ animation: none }
}
