/* =============================================================================
   The book: the home page is an open notebook on a desk.

   Contents
   1. Fonts (the two extra faces the book uses)
   2. Tokens
   3. Desk and reader layout
   4. The book: cover, pages, spine, ribbon, tabs
   5. Page contents: kickers, notes, post-its, stamps, polaroids, timelines
   6. The map (page 1)
   7. Page turning
   8. Controls
   9. Phone layout
  10. Without JavaScript, and print

   Every page is plain HTML in index.html, in reading order. assets/js/book.js
   turns that list into spreads. Without it the pages simply stack.
   ========================================================================== */

/* 1. Fonts ================================================================= */

@font-face {
  font-family: "Newsreader";
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url("../fonts/newsreader.woff2") format("woff2");
}

@font-face {
  font-family: "Newsreader";
  font-style: italic;
  font-weight: 200 800;
  font-display: swap;
  src: url("../fonts/newsreader-italic.woff2") format("woff2");
}

@font-face {
  font-family: "Caveat";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/caveat-500.woff2") format("woff2");
}

@font-face {
  font-family: "Caveat";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/caveat-700.woff2") format("woff2");
}

/* 2. Tokens ================================================================
   Paper and ink stay the same in both themes: the book is an object on the
   desk, and only the desk and the lamp light change.
   ========================================================================== */

:root {
  --font-book: "Newsreader", Georgia, "Times New Roman", serif;
  --font-hand: "Caveat", "Segoe Print", "Bradley Hand", cursive;

  --desk: #e4d3b6;
  --desk-2: #d8c3a0;
  --desk-glow: rgba(255, 236, 200, 0.7);

  --paper: #fbf6e9;
  --paper-edge: #efe5cf;
  --parchment: #efdfbd;
  --line: rgba(78, 112, 160, 0.16);
  --margin-line: rgba(196, 72, 60, 0.32);

  --cover: #5b3a26;
  --cover-dark: #3e2718;

  /* One colour per kind of place, used for the washes on the map and the
     tabs. */
  --study: #8fae7c;
  --work: #d0875c;
  --beyond: #7b9cc4;
  --extra: #d7ae55;

  --leading: 1.6rem;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --desk: #1d1510;
    --desk-2: #140e0a;
    --desk-glow: rgba(255, 190, 120, 0.12);
    --paper: #efe6d2;
    --paper-edge: #dccfb4;
    --parchment: #dfcca4;
  }
}

:root[data-theme="dark"] {
  --desk: #1d1510;
  --desk-2: #140e0a;
  --desk-glow: rgba(255, 190, 120, 0.12);
  --paper: #efe6d2;
  --paper-edge: #dccfb4;
  --parchment: #dfcca4;
}

/* Ink is set on the book itself: the site's dark theme redefines --ink on
   :root, and paper needs dark ink whatever the theme. */
.book {
  --ink: #2f2217;
  --ink-soft: #4a3a2a;
  --ink-faint: #7a6650;
  --pen: #2f4f86;
  --red: #a63d1c;
}

/* 3. Desk and reader =======================================================
   The reader is the book and nothing else: the page-turn buttons sit on
   its left and right edges, halfway up, and the tabs stick out into the
   reader's right padding. (On phones the buttons sit under the book: see 9.)

   With .book-fit on <html> the reader is exactly as tall as the window
   below the header, so nothing scrolls. book.js turns it on only when every
   page fits (see fit() there). Otherwise the pages grow with what is on
   them and the window scrolls, as it does without the script.
   ========================================================================== */

body.desk {
  background-color: var(--desk);
  background-image:
    radial-gradient(60rem 40rem at 50% 30%, var(--desk-glow), transparent 70%),
    linear-gradient(180deg, transparent, var(--desk-2));
}

.reader {
  display: grid;
  grid-template-areas: "book";
  width: min(100% - 2rem, 76rem);
  margin-inline: auto;
  padding: 1rem 2.6rem 1rem 0;
}

.book {
  grid-area: book;
}

/* The buttons share the book's grid area, one at each edge. They sit on
   the cover and the outer margin of the page, where no text runs. */
.reader__controls {
  display: contents;
}

.reader__controls .turn {
  grid-area: book;
  align-self: center;
  z-index: 6;
}

.reader__controls [data-turn="prev"] {
  justify-self: start;
}

.reader__controls [data-turn="next"] {
  justify-self: end;
}

/* No way back from the first spread, no way on from the last. */
.reader__controls .turn:disabled {
  visibility: hidden;
}

/* Fitted, the window never scrolls, not even while a turning page leans
   out past the bottom of the book: a scroll bar coming and going would
   shift the whole book sideways for the length of the turn. Scrolling turns
   the page instead (see book.js), so a swipe must not also pull to refresh
   or go back in the browser's history. */
html.book-fit {
  overflow: hidden;
  overscroll-behavior: none;
}

.book-fit body.desk {
  display: flex;
  flex-direction: column;
  height: 100vh;
  height: 100dvh;
}

.book-fit .reader {
  flex: 1;
  min-height: 0;
  /* Pages stop growing at 46rem. On a tall screen the book sits in the
     middle of the desk instead. */
  grid-template-rows: minmax(0, 47.5rem);
  align-content: center;
}

/* On a short window every line of the page counts: less desk around it. */
@media (max-height: 40rem) {
  .book-fit .reader {
    padding-block: 0.6rem;
  }
}

/* 4. The book ============================================================== */

.book {
  /* The height of a page. With .book-fit it is exactly the height the
     book is given (see below); until then, a guess from the window. */
  --book-h: clamp(30rem, 100dvh - 13.75rem, 46rem);
  /* Type and line spacing shrink a little on short screens. When a page
     would still not fit, book.js lowers --fit, and everything on every
     page shrinks with it: page contents are sized in em for that reason. */
  --fit: 1;
  --leading: calc(clamp(1.25rem, 0.1rem + 2.4vh, 1.6rem) * var(--fit));
  position: relative;
  padding: 0.75rem;
  border-radius: 12px;
  background:
    radial-gradient(
      120% 90% at 30% 20%,
      rgba(255, 255, 255, 0.08),
      transparent
    ),
    var(--cover);
  box-shadow:
    inset 0 0 0 2px var(--cover-dark),
    0 2px 3px rgba(40, 20, 5, 0.3),
    0 30px 60px -30px rgba(40, 20, 5, 0.75);
}

.book__pages {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  perspective: 2600px;
  /* A few sheets of paper visible under the open pages. */
  box-shadow:
    0 2px 0 var(--paper-edge),
    0 4px 0 #e2d6bb,
    0 6px 0 var(--paper-edge);
  border-radius: 4px;
}

/* The fold down the middle. */
.book__pages::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(50% - 2.5rem);
  width: 5rem;
  pointer-events: none;
  z-index: 3;
  background: linear-gradient(
    90deg,
    transparent,
    rgba(60, 35, 10, 0.1) 40%,
    rgba(60, 35, 10, 0.28) 50%,
    rgba(60, 35, 10, 0.1) 60%,
    transparent
  );
}

/* The ribbon bookmark. */
.book::after {
  content: "";
  position: absolute;
  top: -0.3rem;
  /* In the gutter of the left page, where no text runs. */
  left: calc(50% - 1.9rem);
  width: 1rem;
  height: 4.5rem;
  z-index: 4;
  background: linear-gradient(90deg, #8e2a18, #b8432a 50%, #8e2a18);
  clip-path: polygon(0 0, 100% 0, 100% 100%, 50% 82%, 0 100%);
  box-shadow: 0 2px 3px rgba(0, 0, 0, 0.25);
  pointer-events: none;
}

.page {
  position: relative;
  /* Pages are a fixed height, except on short screens, where a page with a
     lot on it grows rather than hiding its end behind a scrollbar. */
  min-height: var(--book-h);
  padding: calc(var(--leading) * 1.5) 2.25rem calc(var(--leading) * 1.6) 3.4rem;
  background-color: var(--paper);
  background-image:
    linear-gradient(
      90deg,
      transparent 2.4rem,
      var(--margin-line) 2.4rem,
      var(--margin-line) calc(2.4rem + 1px),
      transparent calc(2.4rem + 1px)
    ),
    repeating-linear-gradient(
      180deg,
      transparent 0,
      transparent calc(var(--leading) - 1px),
      var(--line) calc(var(--leading) - 1px),
      var(--line) var(--leading)
    );
  background-position:
    0 0,
    0 calc(var(--leading) * 1.5 - 0.3rem);
  color: var(--ink);
  font-family: var(--font-book);
  font-size: calc(clamp(0.9rem, 0.25rem + 1.45vh, 1.02rem) * var(--fit));
  line-height: var(--leading);
  font-variation-settings: "opsz" 14;
}

/* Fitted: the pages share whatever height the book is given, and a page
   never scrolls. book.js has checked that everything fits, so clipping only
   hides a sliver for a moment while the window is being resized. */
.book-fit .book {
  --book-h: 100cqh;
  display: flex;
  flex-direction: column;
}

.book-fit .book__pages {
  flex: 1;
  min-height: 0;
  container-type: size;
}

.book-fit .page {
  min-height: 0;
  overflow: clip;
}

.page.side-left {
  border-radius: 4px 0 0 4px;
  box-shadow: inset -18px 0 22px -18px rgba(60, 35, 10, 0.35);
}

.page.side-right {
  border-radius: 0 4px 4px 0;
  box-shadow: inset 18px 0 22px -18px rgba(60, 35, 10, 0.35);
}

.page__num {
  position: absolute;
  bottom: 0.7rem;
  font-family: var(--font-hand);
  font-size: 1.15em;
  color: var(--ink-faint);
}

.side-left .page__num {
  left: 1.2rem;
}

.side-right .page__num,
.page:not(.side-left) .page__num {
  right: 1.4rem;
}

/* Chapter tabs, sticking out of the right edge of the book. */
.book__tabs {
  position: absolute;
  top: 1.5rem;
  right: -2.6rem;
  bottom: 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  z-index: 0;
}

.tab {
  --tab: var(--paper-edge);
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.3rem;
  max-height: 6.5rem;
  padding: 0.4rem 0;
  writing-mode: vertical-rl;
  font-family: var(--font-hand);
  font-size: 1.1rem;
  font-weight: 700;
  line-height: 1;
  color: var(--ink);
  text-decoration: none;
  background: color-mix(in srgb, var(--tab) 70%, var(--paper));
  border-radius: 0 9px 9px 0;
  box-shadow: 2px 2px 4px rgba(40, 20, 5, 0.25);
  transform: translateX(-0.3rem);
  transition:
    transform 0.2s ease,
    background 0.2s ease;
}

.tab:hover,
.tab[aria-current="true"] {
  transform: none;
  background: var(--tab);
  text-decoration: none;
}

.tab--map {
  --tab: #e9dcc0;
}
.tab--study {
  --tab: var(--study);
}
.tab--work {
  --tab: var(--work);
}
.tab--focus {
  --tab: #c9a2cf;
}
.tab--beyond {
  --tab: var(--beyond);
}
.tab--extra {
  --tab: var(--extra);
}

/* 5. Page contents =========================================================
   Sized in em, relative to the page's type, so that a whole page shrinks
   together when it has to (see --fit in 4). Anything nested inside another
   em-sized box divides by that box's size: a summary at 1.47em inside a
   post-it at 0.92em comes out at 1.35 times the page's type.
   ========================================================================== */

.page h1,
.page h2,
.page h3 {
  font-family: var(--font-display);
  color: var(--ink);
  letter-spacing: -0.01em;
}

.page h2 {
  font-size: 2em;
  line-height: calc(var(--leading) * 1.5);
  margin-bottom: calc(var(--leading) * 0.5);
}

.page h3 {
  font-size: 1.2em;
  line-height: var(--leading);
  margin-top: calc(var(--leading) * 0.75);
}

.page p + p {
  margin-top: calc(var(--leading) * 0.5);
}

.page a {
  color: var(--red);
}

.page em {
  font-style: italic;
}

.page .lead {
  max-width: none;
  font-size: 1.12em;
  color: var(--ink-soft);
}

/* A handwritten line in red above a chapter title. */
.kicker {
  font-family: var(--font-hand);
  font-size: 1.35em;
  font-weight: 700;
  line-height: var(--leading);
  color: var(--red);
}

/* A pencil note in blue ink, slightly off the lines. */
.pen {
  font-family: var(--font-hand);
  font-size: 1.3em;
  line-height: 1.3;
  color: var(--pen);
  transform: rotate(-1.5deg);
}

.pen a {
  color: var(--pen);
}

/* A note in pen in the top corner of a page, beside the kicker: the way
   out to the plain resume, on the first spread. */
.page__note {
  position: absolute;
  top: calc(var(--leading) * 1.5 - 0.1em);
  right: 2.25rem;
  font-family: var(--font-hand);
  font-size: 1.3em;
  line-height: 1.1;
  color: var(--pen);
  rotate: 2deg;
}

.page__note a {
  color: inherit;
  font-weight: 700;
}

/* "Picked up here": a row of highlighter marks under each chapter. */
.picked {
  margin-top: var(--leading);
}

.picked__label {
  font-family: var(--font-hand);
  font-size: 1.2em;
  font-weight: 700;
  color: var(--ink-faint);
}

.picked ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem 0.9rem;
}

.picked li {
  font-weight: 500;
  background: linear-gradient(
    100deg,
    transparent 0.2em,
    rgba(250, 205, 80, 0.55) 0.3em,
    rgba(250, 205, 80, 0.45) calc(100% - 0.3em),
    transparent calc(100% - 0.2em)
  );
  background-size: 100% 0.62em;
  background-position: 0 88%;
  background-repeat: no-repeat;
}

/* Post-it notes. A <details>, so they open without script and are reachable
   by keyboard. */
.postit {
  --tilt: -1.5deg;
  position: relative;
  margin-top: calc(var(--leading) * 0.75);
  padding: 0.6em 1em 0.7em;
  background: #f8e58c;
  color: #3b2f10;
  font-family: var(--font-body);
  font-size: 0.92em;
  line-height: 1.5;
  box-shadow:
    0 1px 1px rgba(0, 0, 0, 0.12),
    0 10px 14px -10px rgba(60, 40, 0, 0.5);
  transform: rotate(var(--tilt));
}

.postit + .postit {
  --tilt: 1.2deg;
}

.postit--pink {
  background: #f6c6c4;
}

.postit--blue {
  background: #cfe3f2;
}

.postit--green {
  background: #d7eab8;
}

.postit summary {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  cursor: pointer;
  list-style: none;
  font-family: var(--font-hand);
  font-size: 1.47em;
  font-weight: 700;
  line-height: 1.25;
}

.postit summary::-webkit-details-marker {
  display: none;
}

.postit summary::after {
  content: "+";
  margin-left: auto;
  font-family: var(--font-body);
  font-size: 0.81em;
  font-weight: 700;
  opacity: 0.6;
}

.postit[open] summary::after {
  content: "−";
}

.postit summary small {
  font-family: var(--font-body);
  font-size: 0.59em;
  font-weight: 500;
  opacity: 0.75;
}

.postit > p,
.postit > ul {
  margin-top: 0.38em;
}

.postit a {
  color: inherit;
  font-weight: 700;
}

/* A post-it that is only a note, nothing to open. */
.postit--static {
  padding: 0.46em 0.77em 0.54em;
  font-family: var(--font-hand);
  font-size: 1.3em;
  line-height: 1.25;
}

.postit--static strong {
  display: block;
  font-size: 1.69em;
  line-height: 1;
}

/* A strip of tape. Put it inside anything with position: relative. */
.tape {
  position: absolute;
  top: -0.7rem;
  left: 50%;
  width: 5.5rem;
  height: 1.4rem;
  translate: -50% 0;
  rotate: -3deg;
  background: rgba(236, 226, 196, 0.72);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12);
  backdrop-filter: blur(1px);
}

.polaroid {
  position: relative;
  width: fit-content;
  max-width: 100%;
  margin: calc(var(--leading) * 0.5) auto calc(var(--leading) * 0.25);
  padding: 0.55em 0.55em 0.3em;
  background: #fff;
  box-shadow:
    0 1px 2px rgba(0, 0, 0, 0.15),
    0 12px 22px -14px rgba(40, 20, 5, 0.55);
  rotate: 1.2deg;
}

.polaroid img {
  display: block;
  width: auto;
  max-width: 100%;
  height: auto;
  /* Photos are sized by the height of the page, so they never push the
     text off it. */
  max-height: calc(var(--book-h) * 0.27 * var(--fit));
  border: 0;
  border-radius: 0;
  box-shadow: none;
}

/* Until the photo is added: the same height the photo will get. */
.polaroid .placeholder {
  display: grid;
  width: auto;
  height: calc(var(--book-h) * 0.27 * var(--fit));
  border-radius: 0;
}

.polaroid figcaption {
  margin-top: 0.1rem;
  font-family: var(--font-hand);
  font-size: 1.2em;
  line-height: 1.5;
  text-align: center;
  color: var(--ink-soft);
}

/* A photo that turns to its chapter, with a pen note beside it that opens
   the app. Where the column is too narrow for the note beside the photo, it
   goes on one line under it, so the block is never taller than a photo and
   a line of text. */
.featured {
  container-type: inline-size;
}

.featured__row {
  display: grid;
  grid-template-columns: minmax(4.6em, 1fr) minmax(0, auto) minmax(4.6em, 1fr);
  align-items: center;
  column-gap: 0.4em;
}

.featured .polaroid {
  grid-column: 2;
  transition:
    rotate 0.2s ease,
    scale 0.2s ease;
}

.featured .polaroid > a {
  display: block;
}

.featured .polaroid:has(> a:hover, > a:focus-visible) {
  rotate: 0deg;
  scale: 1.02;
}

.featured__note {
  grid-column: 3;
  display: grid;
  justify-items: center;
  font-family: var(--font-hand);
  font-size: 1.3em;
  font-weight: 700;
  line-height: 1;
  text-align: center;
  text-decoration: none;
  rotate: 5deg;
  transition: rotate 0.2s ease;
}

/* Blue pen ink, like the other notes, instead of the red of page links. */
.featured .featured__note {
  color: var(--pen);
}

.featured .featured__note:hover,
.featured .featured__note:focus-visible {
  color: var(--red);
  rotate: 0deg;
}

.featured__note svg {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.featured__planet {
  width: 1.7em;
  height: 1.35em;
  margin-bottom: 0.15em;
}

/* An underline that ends in an arrow pointing out: the app opens in a new
   tab. */
.featured__swoosh {
  width: 2.9em;
  height: 0.9em;
  margin-top: 0.1em;
}

@container (max-width: 22em) {
  .featured__row {
    grid-template-columns: 1fr;
  }

  .featured .polaroid,
  .featured__note {
    grid-column: 1;
  }

  .featured__note {
    display: block;
    rotate: none;
    text-decoration: underline wavy;
    text-decoration-thickness: 1px;
    text-underline-offset: 0.2em;
  }

  .featured__note br,
  .featured__note svg {
    display: none;
  }
}

/* An index card, clipped to the page. */
.card-note {
  position: relative;
  margin-top: var(--leading);
  padding: 0.82em 1.03em 0.93em;
  background: #fffdf7;
  border: 1px solid #e8dcc2;
  border-top: 3px solid var(--card, var(--red));
  box-shadow: 0 10px 18px -14px rgba(40, 20, 5, 0.6);
  font-size: 0.97em;
  line-height: 1.5;
}

.card-note h3 {
  margin-top: 0;
  font-size: 1.13em;
  line-height: 1.3;
}

.card-note p {
  margin-top: 0.36em;
}

.card-note .kicker {
  font-size: 1.19em;
  line-height: 1.2;
}

/* A paperclip, drawn in CSS: two nested rounded outlines. */
.card-note--clip::before {
  content: "";
  position: absolute;
  top: -0.9rem;
  right: 1.4rem;
  width: 0.7rem;
  height: 2.4rem;
  border: 2px solid #8b8f96;
  border-radius: 0.5rem;
  box-shadow: inset 0 0 0 2px #fffdf7;
  outline: 2px solid #8b8f96;
  outline-offset: 2px;
}

/* A rubber stamp. */
.stamp {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  margin-top: var(--leading);
  padding: 0.51em 1.28em;
  border: 3px double var(--red);
  border-radius: 6px;
  color: var(--red);
  text-align: center;
  text-decoration: none;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-family: var(--font-body);
  font-size: 0.78em;
  font-weight: 700;
  line-height: 1.35;
  rotate: -4deg;
  opacity: 0.88;
}

.stamp strong {
  font-family: var(--font-display);
  font-size: 1.6em;
  letter-spacing: 0.02em;
}

a.stamp:hover {
  opacity: 1;
}

/* A timeline drawn in pencil: a year and what happened, nothing to click. */
.pencil-line {
  margin-top: calc(var(--leading) * 0.5);
  border-left: 2px solid rgba(60, 45, 30, 0.35);
  margin-left: 0.4rem;
}

.pencil-line li {
  position: relative;
  padding-left: 1.1em;
}

.pencil-line li::before {
  content: "";
  position: absolute;
  left: -0.4em;
  top: calc(var(--leading) / 2 - 0.3em);
  width: 0.7em;
  height: 0.7em;
  border-radius: 50%;
  background: var(--paper);
  border: 2px solid var(--ink-soft);
}

.pencil-line b {
  font-family: var(--font-hand);
  font-size: 1.25em;
  color: var(--red);
  margin-right: 0.3em;
}

/* A short list of places to go. */
.arrows li::before {
  content: "→ ";
  font-family: var(--font-hand);
  font-weight: 700;
  color: var(--red);
}

/* Words set as skill chips on the skills pages. */
.marks {
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem 0.75rem;
  margin-top: 0.2rem;
}

.from {
  font-family: var(--font-hand);
  font-size: 1.15em;
  color: var(--ink-faint);
}

.page .tbd {
  font-size: 0.8em;
}

/* 6. The map ===============================================================
   A sheet of parchment taped into page 1. Places are positioned on a
   600 x 720 grid (--x, --y, the middle of the drawing), the same grid as
   the drawing underneath, so the paths always run through them. Below 22rem
   wide the map becomes a list.

   Three kinds of path, explained by the key under the title: the main trail
   (big red dots) runs through school, degrees and jobs. Small dots lead from
   a stop to something that happened within it: an internship, a thesis. A
   parallel line (thin dashes) is something that ran alongside. The places
   at the end of those are .place--sub: drawn smaller, and indented in the
   list. A landmark (.place--static) is context, with no chapter to open.
   ========================================================================== */

.page--map {
  /* The map turns into a list when the page is narrow (a phone), not when
     the map is: on a short screen the drawing just gets smaller, because
     the page is too short for a list. */
  container: map-page / inline-size;
  display: grid;
  place-items: center;
  padding: 1.1rem 1.2rem 1.6rem 3rem;
}

.map {
  container-type: inline-size;
  position: relative;
  width: min(100%, calc((var(--book-h) - 3rem) * 600 / 720));
  filter: drop-shadow(0 8px 10px rgba(60, 35, 10, 0.3));
  rotate: -0.6deg;
}

.map > .tape {
  z-index: 2;
}

.map > .tape--left {
  top: -0.5rem;
  left: 8%;
  rotate: -28deg;
}

.map > .tape--right {
  top: auto;
  bottom: -0.4rem;
  left: 92%;
  rotate: -24deg;
}

.map__paper {
  position: relative;
  /* The washes behind the drawings sit at z-index -1: keep them on the
     paper, in the list view too. */
  isolation: isolate;
  aspect-ratio: 600 / 720;
  background-color: var(--parchment);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='420' height='420'%3E%3Cfilter id='c'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.012' numOctaves='4' seed='7' stitchTiles='stitch'/%3E%3CfeDiffuseLighting lighting-color='%23fff' surfaceScale='2.2'%3E%3CfeDistantLight azimuth='225' elevation='58'/%3E%3C/feDiffuseLighting%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23c)'/%3E%3C/svg%3E");
  background-blend-mode: multiply;
  box-shadow: inset 0 0 3.5rem rgba(120, 75, 25, 0.38);
  clip-path: polygon(
    0% 0.26%,
    3.57% 0.11%,
    7.14% 0.44%,
    10.71% 0.17%,
    14.29% 0.07%,
    17.86% 0.44%,
    21.43% 1.01%,
    25% 0.88%,
    28.57% 0.84%,
    32.14% 0.24%,
    35.71% 0.59%,
    39.29% 0.3%,
    42.86% 0.19%,
    46.43% 0.12%,
    50% 0.24%,
    53.57% 1.02%,
    57.14% 0.91%,
    60.71% 0.89%,
    64.29% 0.88%,
    67.86% 0.21%,
    71.43% 0.34%,
    75% 0.69%,
    78.57% 0.81%,
    82.14% 0.94%,
    85.71% 0.97%,
    89.29% 0.1%,
    92.86% 0.67%,
    96.43% 0.74%,
    99.54% 0%,
    99.84% 3.57%,
    99.57% 7.14%,
    99.92% 10.71%,
    99.16% 14.29%,
    99.22% 17.86%,
    99.51% 21.43%,
    99.73% 25%,
    99.18% 28.57%,
    99.48% 32.14%,
    99.21% 35.71%,
    99.24% 39.29%,
    99.54% 42.86%,
    99.63% 46.43%,
    99.46% 50%,
    99.61% 53.57%,
    99.85% 57.14%,
    99.73% 60.71%,
    99.27% 64.29%,
    99.96% 67.86%,
    99.96% 71.43%,
    99.44% 75%,
    99.75% 78.57%,
    99.52% 82.14%,
    99.58% 85.71%,
    99.69% 89.29%,
    99.1% 92.86%,
    99.82% 96.43%,
    100% 99.55%,
    96.43% 99.78%,
    92.86% 99.3%,
    89.29% 99.7%,
    85.71% 99.61%,
    82.14% 99.18%,
    78.57% 99.65%,
    75% 99.39%,
    71.43% 99.01%,
    67.86% 99.89%,
    64.29% 99.93%,
    60.71% 99.75%,
    57.14% 99.16%,
    53.57% 99.32%,
    50% 99.74%,
    46.43% 99.64%,
    42.86% 99.8%,
    39.29% 99.5%,
    35.71% 99.95%,
    32.14% 99.23%,
    28.57% 99.01%,
    25% 98.95%,
    21.43% 99.19%,
    17.86% 98.94%,
    14.29% 99.98%,
    10.71% 99.68%,
    7.14% 98.94%,
    3.57% 99.15%,
    0.37% 100%,
    0.85% 96.43%,
    0.56% 92.86%,
    0.74% 89.29%,
    0.26% 85.71%,
    0.17% 82.14%,
    0.4% 78.57%,
    0.12% 75%,
    0.34% 71.43%,
    0.87% 67.86%,
    0.3% 64.29%,
    0.01% 60.71%,
    0.04% 57.14%,
    0.15% 53.57%,
    0.71% 50%,
    0.33% 46.43%,
    0.26% 42.86%,
    0.09% 39.29%,
    0.88% 35.71%,
    0.38% 32.14%,
    0.19% 28.57%,
    0.05% 25%,
    0.05% 21.43%,
    0.15% 17.86%,
    0.61% 14.29%,
    0.13% 10.71%,
    0.04% 7.14%,
    0.44% 3.57%
  );
}

.map__art {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  color: #5a4128;
}

.map__title {
  position: absolute;
  top: 3.2%;
  left: 50%;
  width: 88%;
  translate: -50% 0;
  text-align: center;
  font-family: var(--font-hand);
  line-height: 1.1;
  color: var(--ink-soft);
}

.map__title p {
  font-size: 4.4cqw;
  font-weight: 500;
}

.map__title h1 {
  margin: 0.3cqw 0 0.6cqw;
  font-family: var(--font-display);
  font-size: 6.6cqw;
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.02em;
  color: var(--ink);
}

.map__places {
  margin: 0;
}

/* --x and --y put the middle of the drawing on the grid. The label hangs
   below it, or beside it with --label-right and --label-left. */
.place {
  --icon: 11cqw;
  --label: 3.9cqw;
  --note: 2.9cqw;
  position: absolute;
  left: calc(var(--x) / 600 * 100%);
  top: calc(var(--y) / 720 * 100%);
  translate: -50% calc(var(--icon) / -2);
}

/* A link to the place's chapter, or for a landmark a plain <span>. */
.place > :is(a, span) {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4cqw;
  color: var(--ink);
  text-decoration: none;
}

.place--label-right > :is(a, span) {
  flex-direction: row;
  gap: 1cqw;
  translate: calc(50% - var(--icon) / 2) 0;
}

.place--label-left > :is(a, span) {
  flex-direction: row-reverse;
  gap: 1cqw;
  translate: calc(-50% + var(--icon) / 2) 0;
}

.place--label-right .place__label,
.place--label-left .place__label {
  text-align: left;
}

.place--label-left .place__label {
  text-align: right;
}

.place__icon {
  --wash: var(--work);
  position: relative;
  display: grid;
  place-items: center;
  width: var(--icon);
  height: var(--icon);
  color: #3a2818;
  transition: transform 0.2s ease;
}

/* A watercolour wash behind each drawing, in the colour of its kind. */
.place__icon::before {
  content: "";
  position: absolute;
  inset: 4%;
  z-index: -1;
  border-radius: 58% 42% 55% 45% / 45% 55% 45% 55%;
  background: radial-gradient(
    circle at 40% 40%,
    color-mix(in srgb, var(--wash) 70%, transparent),
    color-mix(in srgb, var(--wash) 35%, transparent) 70%,
    transparent 72%
  );
}

.place__icon svg {
  width: 82%;
  height: 82%;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.place--study .place__icon {
  --wash: var(--study);
}
.place--beyond .place__icon {
  --wash: var(--beyond);
}
.place--extra .place__icon {
  --wash: var(--extra);
}
.place--focus .place__icon {
  --wash: #c9a2cf;
}

.place__label {
  font-family: var(--font-hand);
  font-size: var(--label);
  font-weight: 700;
  line-height: 0.95;
  text-align: center;
  white-space: nowrap;
}

.place__label small {
  display: block;
  font-size: var(--note);
  font-weight: 500;
  color: var(--ink-faint);
}

/* What happened within a stop, what ran in parallel, life beyond work and
   landmarks are drawn smaller than the stops. Focusverse runs in parallel
   but is featured, so it keeps its size. */
.place--sub:not(.place--featured),
.place--beyond,
.place--static {
  --icon: 7.5cqw;
  --label: 3.4cqw;
  --note: 2.7cqw;
}

/* A landmark is plain ink: no wash, and nothing to open. */
.place--static .place__icon::before {
  display: none;
}

.place--static .place__label {
  color: var(--ink-soft);
}

.place a:hover .place__icon,
.place a:focus-visible .place__icon {
  transform: rotate(-6deg) scale(1.08);
}

.place a:hover .place__label,
.place a:focus-visible .place__label {
  color: var(--red);
}

.place--here .place__label {
  color: var(--red);
}

/* The key to the three kinds of path, in one row under the title. Each
   sample is drawn on the same scale as the map. The colours need no key:
   the tabs on the edge of the book name them. */
.map__key {
  position: absolute;
  top: 19.2%;
  left: 0;
  right: 0;
  display: flex;
  justify-content: center;
  gap: 2.6cqw;
  font-family: var(--font-hand);
  font-size: 3cqw;
  font-weight: 500;
  line-height: 1.15;
  color: var(--ink-soft);
}

.map__key li {
  display: flex;
  align-items: center;
  gap: 1cqw;
  white-space: nowrap;
}

.map__key svg {
  flex: none;
  width: 5cqw;
  height: 1.2cqw;
  fill: none;
  stroke-linecap: round;
}

/* 7. Page turning ==========================================================
   book.js lays a "leaf" over the half being turned: its front is a copy of
   the page going away, its back a copy of the page arriving. It rotates
   around the spine and is removed when it lands.
   ========================================================================== */

.leaf {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 50%;
  z-index: 5;
  transform-style: preserve-3d;
  pointer-events: none;
}

.leaf--forward {
  left: 50%;
  transform-origin: left center;
  animation: turn-forward 0.7s cubic-bezier(0.45, 0.05, 0.3, 1) forwards;
}

.leaf--back {
  left: 0;
  transform-origin: right center;
  animation: turn-back 0.7s cubic-bezier(0.45, 0.05, 0.3, 1) forwards;
}

.leaf > .page {
  position: absolute;
  inset: 0;
  min-height: 0;
  overflow: hidden;
  backface-visibility: hidden;
}

.leaf > .leaf__back {
  transform: rotateY(180deg);
}

/* A shadow that darkens the face of the leaf as it lifts. */
.leaf > .page::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(90deg, rgba(40, 20, 5, 0.25), transparent 60%);
  opacity: 0;
  animation: leaf-shade 0.7s ease forwards;
}

@keyframes turn-forward {
  to {
    transform: rotateY(-180deg);
  }
}

@keyframes turn-back {
  to {
    transform: rotateY(180deg);
  }
}

@keyframes leaf-shade {
  50% {
    opacity: 1;
  }
}

/* On one-page screens a turn is a short slide. */
.page.enter-next {
  animation: slide-in-next 0.35s ease;
}

.page.enter-prev {
  animation: slide-in-prev 0.35s ease;
}

@keyframes slide-in-next {
  from {
    opacity: 0;
    transform: translateX(1.5rem);
  }
}

@keyframes slide-in-prev {
  from {
    opacity: 0;
    transform: translateX(-1.5rem);
  }
}

@media (prefers-reduced-motion: reduce) {
  .leaf,
  .leaf > .page::after,
  .page.enter-next,
  .page.enter-prev {
    animation-duration: 1ms;
  }
}

/* 8. Controls ==============================================================
   Round buttons in the cover's leather, ringed in paper so they read on
   the cover and on the page alike. Where they sit is part of the reader's
   layout: see 3, and 9 for phones.
   ========================================================================== */

.turn {
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  padding: 0;
  border: 2px solid var(--paper-edge);
  border-radius: 50%;
  color: var(--paper);
  background: var(--cover);
  box-shadow: 0 6px 12px -6px rgba(40, 20, 5, 0.6);
  cursor: pointer;
  transition: transform 0.15s ease;
}

.turn:hover:not(:disabled) {
  transform: scale(1.07);
}

.turn:disabled {
  opacity: 0.35;
  cursor: default;
}

.turn svg {
  width: 1.1rem;
  height: 1.1rem;
}

/* Corner hot spots on the outer edges: click the corner to turn. */
.corner {
  position: absolute;
  bottom: 0;
  z-index: 4;
  width: 3.2rem;
  height: 3.2rem;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
}

.corner--prev {
  left: 0;
}

.corner--next {
  right: 0;
}

.corner::before {
  content: "";
  position: absolute;
  bottom: 0;
  width: 0;
  height: 0;
  transition:
    width 0.2s ease,
    height 0.2s ease;
}

.corner--next::before {
  right: 0;
  background: linear-gradient(
    315deg,
    var(--desk) 50%,
    #e8dcc3 50%,
    #fffaf0 80%
  );
  box-shadow: -3px -3px 6px rgba(40, 20, 5, 0.18);
}

.corner--prev::before {
  left: 0;
  background: linear-gradient(45deg, var(--desk) 50%, #e8dcc3 50%, #fffaf0 80%);
  box-shadow: 3px -3px 6px rgba(40, 20, 5, 0.18);
}

.corner:hover::before,
.corner:focus-visible::before {
  width: 2.4rem;
  height: 2.4rem;
}

.corner:disabled {
  display: none;
}

/* 9. Phone layout ========================================================== */

@media (max-width: 59.99em) {
  /* One column: the book, with the buttons under it, sticking to the bottom
     of the screen while a long page scrolls past. A flex column rather than
     the grid, because a grid item cannot stick. */
  .reader {
    display: flex;
    flex-direction: column;
    width: min(100% - 1rem, 40rem);
    padding: 1rem 0 1.25rem;
  }

  .book {
    padding: 0.45rem;
  }

  .book-fit .reader {
    justify-content: center;
  }

  .book-fit .book {
    flex: 1;
    max-height: 52rem;
  }

  .book::after {
    left: 80%;
  }

  .book__pages {
    grid-template-columns: 1fr;
  }

  .book__pages::after {
    display: none;
  }

  .page {
    height: auto;
    min-height: 30rem;
    overflow: visible;
    padding: calc(var(--leading) * 1.25) 1.1rem calc(var(--leading) * 2.25)
      2.6rem;
    background-image:
      linear-gradient(
        90deg,
        transparent 1.9rem,
        var(--margin-line) 1.9rem,
        var(--margin-line) calc(1.9rem + 1px),
        transparent calc(1.9rem + 1px)
      ),
      repeating-linear-gradient(
        180deg,
        transparent 0,
        transparent calc(var(--leading) - 1px),
        var(--line) calc(var(--leading) - 1px),
        var(--line) var(--leading)
      );
  }

  .page.side-left,
  .page.side-right {
    border-radius: 4px;
    box-shadow: none;
  }

  .page__num,
  .side-left .page__num {
    left: auto;
    right: 1.2rem;
  }

  .page--map {
    padding: 1rem 0.8rem 2rem 2.2rem;
  }

  /* A page that grows can give the map its full width. A fitted page keeps
     it within the page's height (see 6). */
  html:not(.book-fit) .map {
    width: 100%;
  }

  /* Tabs turn into a row of index tabs above the book, over the ribbon that
     hangs from that same edge, so it tucks under them instead of covering
     a label. Positioned only for that; the offsets that pin them to the
     book's side above do not apply. */
  .book__tabs {
    position: relative;
    inset: auto;
    z-index: 5;
    flex-direction: row;
    gap: 0.25rem;
    margin: -0.45rem -0.45rem 0.45rem;
    padding: 0 0.25rem;
    overflow-x: auto;
    scrollbar-width: none;
  }

  .tab {
    flex: none;
    width: auto;
    max-height: none;
    padding: 0.45rem 0.7rem 0.3rem;
    writing-mode: horizontal-tb;
    border-radius: 0 0 9px 9px;
    transform: translateY(-0.2rem);
  }

  .reader__controls {
    position: sticky;
    bottom: 0.5rem;
    z-index: 10;
    display: flex;
    align-self: center;
    gap: 0.75rem;
    margin-top: 1rem;
    padding: 0.4rem;
    border-radius: 999px;
    background: color-mix(in srgb, var(--desk) 85%, transparent);
    backdrop-filter: blur(8px);
  }

  .reader__controls .turn:disabled {
    visibility: visible;
  }

  .page__note {
    right: 1.1rem;
  }

  .corner {
    display: none;
  }
}

/* Too narrow for the note to share a line with the kicker. */
@media (max-width: 24.99em) {
  .page__note {
    position: static;
    margin-bottom: 0.3rem;
    text-align: right;
  }
}

/* The map as a list, when the page is too narrow for the drawing to be
   legible. */
@container map-page (max-width: 22rem) {
  .map__paper {
    aspect-ratio: auto;
    padding: 1.2rem 1rem 1.5rem;
    clip-path: none;
  }

  .map__art {
    display: none;
  }

  .map__title {
    position: static;
    width: auto;
    translate: none;
  }

  .map__title p {
    font-size: 1.2rem;
  }

  .map__title h1 {
    font-size: 1.9rem;
  }

  .map__places {
    position: relative;
    display: grid;
    gap: 0.35rem;
    margin-top: 1rem;
  }

  .map__places::before {
    content: "";
    position: absolute;
    left: 1.5rem;
    top: 1rem;
    bottom: 1rem;
    border-left: 3px dotted var(--red);
    opacity: 0.6;
  }

  .place {
    --icon: 3rem;
    --label: 1.35rem;
    --note: 1rem;
    position: relative;
    left: auto;
    top: auto;
    translate: none;
  }

  /* What happened within a stop, or ran alongside it, hangs off that stop. */
  .place--sub {
    margin-left: 1.75rem;
  }

  .place--sub:not(.place--featured) {
    --icon: 2.25rem;
    --label: 1.2rem;
    --note: 0.95rem;
  }

  .place > :is(a, span),
  .place--label-right > :is(a, span),
  .place--label-left > :is(a, span) {
    flex-direction: row;
    gap: 0.75rem;
    translate: none;
  }

  .place__icon {
    flex: none;
  }

  .place__label,
  .place--label-left .place__label {
    text-align: left;
  }

  /* The list draws no paths, so there is nothing for the key to explain. */
  .map__key {
    display: none;
  }
}

/* 10. Without JavaScript, and print ======================================== */

/* Until book.js has run (or if it never does), pages stack like a notepad. */
html:not(.js-book) .book__pages {
  grid-template-columns: 1fr;
  gap: 1rem;
  box-shadow: none;
}

/* No spread, so no spine and no ribbon in its gutter, which would lie across
   the text of the first page. */
html:not(.js-book) .book::after,
html:not(.js-book) .book__pages::after,
html:not(.js-book) .reader__controls,
html:not(.js-book) .corner {
  display: none;
}

html:not(.js-book) .page {
  height: auto;
  overflow: visible;
}

.js-book .page[hidden] {
  display: none;
}

@media print {
  html.book-fit {
    overflow: visible;
  }

  body.desk,
  .book-fit body.desk {
    display: block;
    height: auto;
    background: #fff;
  }

  .reader {
    display: block;
    width: auto;
    padding: 0;
  }

  .book,
  .book-fit .book {
    display: block;
    margin: 0;
    padding: 0;
    background: none;
    box-shadow: none;
  }

  .book-fit .book__pages {
    container-type: normal;
  }

  .book::after,
  .book__tabs,
  .book__pages::after,
  .page__note,
  .reader__controls,
  .corner,
  .leaf {
    display: none !important;
  }

  .book__pages {
    display: block;
    box-shadow: none;
  }

  .page,
  .book-fit .page,
  .js-book .page[hidden] {
    display: block !important;
    height: auto;
    overflow: visible;
    break-after: page;
    box-shadow: none;
  }

  .postit:not([open]) > :not(summary) {
    display: block;
  }
}
