* { box-sizing: border-box; }
:root { color-scheme: light; background: #fff; color: #555; font: 16px/1.5 Arial, sans-serif; }
body { margin: 0; min-height: 100svh; }
.publication { margin: 0; padding: 10px 10px 20px; text-align: center; }
.publication-image { display: block; width: auto; height: auto; max-width: 100%; max-height: calc(100svh - 30px); margin: 0 auto; box-shadow: 0 5px 15px rgb(0 0 0 / 18%); }
.publication--coming-soon .publication-image { max-height: calc(100svh - 74px); }
.publication figcaption { margin-top: 20px; }

/* TAOAM landing page: the three companion cards beside the Volume I cover.
   The cards set the height and the cover matches it, top edge to bottom edge,
   so the two columns read as one block rather than as a tall stack next to a
   short picture. That is why the columns are not equal: a portrait cover as
   tall as three landscape cards is wider than half the row, so the card column
   is fixed at its own maximum and the cover takes what is left.

   "Coming soon" hangs below that shared bottom edge, out of flow, so it can
   sit under the cover without being part of what the two columns align to.
   Stacked, all four fill the single column and the caption returns to flow. */
.taoam-page {
  --taoam-gap: clamp(20px, 3.2vw, 56px);
  --taoam-stack-gap: clamp(36px, 6svh, 72px);
  --taoam-card-max: 420px;
}
.taoam-page main {
  display: flex;
  min-height: calc(100svh - 36px);
  padding: clamp(92px, 12svh, 132px) 20px 48px;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start; /* top positioned; padding-top is the margin */
}
.taoam-row {
  display: grid;
  width: 100%;
  grid-template-columns: min(100%, 720px);
  justify-content: center;
  gap: var(--taoam-stack-gap);
}
.taoam-cards {
  display: flex;
  min-width: 0;
  flex-direction: column;
  gap: var(--taoam-stack-gap);
}
.taoam-item {
  position: relative;
  display: block;
  flex: 0 0 auto;
  line-height: 0;
}
.taoam-item > img {
  display: block;
  width: 100%;
  height: auto;
  box-shadow: 0 24px 48px rgb(0 0 0 / 22%), 0 8px 16px rgb(0 0 0 / 14%);
}
.taoam-card > img { border: 1px solid #c8c8c8; }
.taoam-card .taoam-click-indicator {
  position: absolute;
  top: 8%;
  right: 4%;
  width: clamp(24px, 6%, 40px);
  border: 0;
  box-shadow: none;
  pointer-events: none;
}
.taoam-card:focus-visible { outline: 2px solid #0048A0; outline-offset: 6px; }
.taoam-book { position: relative; width: 100%; min-width: 0; }
/* .taoam-item zeroes line-height for the images it usually holds. */
.taoam-coming {
  margin: 14px 0 0;
  color: #8A909B;
  font-size: 14px;
  line-height: 1.4;
  text-align: center;
}
.taoam-page .site-footer { position: static; }

@media (min-width: 1040px) and (min-height: 780px) {
  /* The cover's height cannot be taken from the card column at render time:
     asking for 100% of a row whose height the cover itself is contributing to
     is circular, and the browser resolves it by falling back to the column's
     width -- which makes the cover enormous and stretches the cards to match.
     So the stack is measured instead. All three cards are one 980x526 artwork
     at the column's own width, so their height is arithmetic, not a guess --
     allowing for the 1px card border, which border-box takes out of the
     picture's height and then adds back around it. */
  .taoam-page {
    --taoam-card-gap: clamp(48px, 7svh, 90px);
    --taoam-stack-height: calc(
      3 * ((var(--taoam-card-max) - 2px) * 526 / 980 + 2px)
      + 2 * var(--taoam-card-gap));
  }
  .taoam-row {
    grid-template-columns: var(--taoam-card-max) auto;
    justify-content: center;
    align-items: start;
    gap: var(--taoam-gap);
  }
  .taoam-cards {
    width: 100%;
    gap: var(--taoam-card-gap);
  }
  .taoam-book { width: auto; }
  /* Height drives width, so the cover keeps its proportions exactly and the
     column is only ever as wide as the cover needs. The second term is the
     width actually left in the row: below roughly 1135px the cover would have
     to spill out of the page to reach the cards' bottom edge, so it stops at
     what fits and the two columns simply share their top edge, as before. */
  .taoam-book > img {
    width: auto;
    height: min(
      var(--taoam-stack-height),
      calc((100vw - 40px - var(--taoam-card-max) - var(--taoam-gap)) * 1426 / 1103)
    );
  }
  /* Below the bottom edge the two columns share, not part of it. */
  .taoam-coming {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
  }
  /* Out of flow means main's box ends at that shared edge and the caption
     hangs past it, so the room it needs is reserved here instead -- its own
     offset and line, in place of most of the padding it now sits inside. */
  .taoam-page main { padding-bottom: calc(24px + 14px + 1.4em); }
}

/* On small screens keep the menu above, rather than over, the artwork. */
@media (max-width: 760px) {
  .publication { padding-top: 64px; }
  .publication-image { max-height: calc(100svh - 84px); }
  .publication--coming-soon .publication-image { max-height: calc(100svh - 128px); }
  .taoam-page main { padding: clamp(88px, 11svh, 104px) 16px 24px; }
}

@font-face {
  font-family: "Latin Modern Sans";
  src: url("/assets/fonts/lmsans10-regular.otf") format("opentype");
  font-style: normal;
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Latin Modern Sans";
  src: url("/assets/fonts/lmsans10-bold.otf") format("opentype");
  font-style: normal;
  font-weight: 700;
  font-display: swap;
}
/* Clear the header band: 10px top + 44px button/logo + breathing room. */
.subatomic-page { padding-top: clamp(78px, 9svh, 96px); }
.publication-header {
  max-width: 1226px;
  margin: 0 auto 24px;
  padding: 0 20px;
  text-align: center;
  color: #0048A0;
  font-family: "Latin Modern Sans", Arial, sans-serif;
}
.publication-header h1 {
  margin: 0;
  font-size: clamp(28px, 3.2vw, 46px);
  font-weight: 700;
  line-height: 1.12;
}
.publication-header p {
  margin: 14px 0 0;
  font-size: clamp(18px, 1.6vw, 24px);
  font-weight: 400;
  line-height: 1.4;
}
.subatomic-page .publication { padding-top: 0; }

/* Snapshot Pages access modal.

   Shown only when the Worker turns an unverified reader away and sends them
   back with ?verify=1. It explains which topics unlock the pages; it never
   makes an access decision and never sees a key. */
.access-overlay {
  position: fixed;
  inset: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(0, 0, 0, 0.45);
}
.access-dialog {
  box-sizing: border-box;
  width: min(30rem, 100%);
  max-height: calc(100svh - 40px);
  overflow-y: auto;
  padding: clamp(22px, 4vw, 34px);
  border-radius: 4px;
  background: #fff;
  color: #555;
  text-align: left;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
}
.access-title {
  margin: 0 0 14px;
  color: #333;
  font-size: 1.2rem;
  font-weight: bold;
  line-height: 1.35;
}
.access-lead { margin: 0 0 18px; }
.access-topics {
  margin: 0 0 20px;
  padding: 0;
  list-style: none;
}
.access-topics li {
  padding: 9px 0;
  border-top: 1px solid #e4e4e4;
}
.access-topics li:last-child { border-bottom: 1px solid #e4e4e4; }
/* The volume label sits above the title rather than beside it: topic names run
   long enough that a two-column row wraps awkwardly on a phone. */
.access-volume {
  display: block;
  color: #767676;
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.access-topic {
  display: block;
  color: #333;
  font-weight: bold;
}
.access-note {
  margin: 0 0 20px;
  color: #767676;
  font-size: 0.75rem;
  line-height: 1.5;
}
/* Try again sits first and filled; Close is the quieter way out. On a phone
   they stack, so the primary action stays under the thumb either way. */
.access-actions {
  display: flex;
  flex-direction: row-reverse;
  gap: 10px;
}
.access-button {
  flex: 1;
  padding: 11px 18px;
  border: 1px solid #0048A0;
  border-radius: 3px;
  font: inherit;
  cursor: pointer;
}
.access-button--primary { background: #0048A0; color: #fff; }
.access-button--primary:hover { background: #00336F; }
.access-button--secondary { background: #fff; color: #0048A0; }
.access-button--secondary:hover { background: #EEF3FA; }
.access-button:disabled { opacity: 0.6; cursor: default; }
.access-button:focus-visible { outline: 2px solid #0048A0; outline-offset: 3px; }
@media (max-width: 26rem) {
  .access-actions { flex-direction: column; }
}
body.access-open { overflow: hidden; }

/* The Snapshot Pages hub: four volumes, no contents.

   Each volume is unlocked by its own book, so the hub names them and stops
   there. The locked styling is applied by script after asking the Worker
   which volumes this browser holds; it is presentation only, and the volume
   pages are gated server-side regardless of what this looks like. */
.snapshots-volumes {
  display: grid;
  /* Equal-height rows: volume titles wrap to two lines at some widths, and a
     card should not be shorter just because its title is short. */
  grid-auto-rows: 1fr;
  gap: 14px;
  max-width: 46rem;
  margin: 0 auto;
  padding: 0;
  list-style: none;
}
.snapshots-volume-card > a {
  display: flex;
  flex-direction: column;
  height: 100%;
  box-sizing: border-box;
  padding: 16px 18px;
  border: 1px solid #d8d8d8;
  border-left: 4px solid var(--snap-accent, #174A8B);
  border-radius: 3px;
  color: inherit;
  text-decoration: none;
}
.snapshots-volume-card > a:hover { background: #F7F9FC; }
.snapshots-volume-card > a:focus-visible { outline: 2px solid #0048A0; outline-offset: 3px; }
.snapshots-volume-name {
  display: block;
  color: var(--snap-accent, #174A8B);
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.snapshots-volume-title { display: block; color: #333; font-weight: bold; }
.snapshots-volume-count { display: block; color: #767676; font-size: 0.8rem; }
/* Muted rather than hidden: a reader should be able to see that the other
   volumes exist and how to open them. */
.snapshots-volume-card.is-locked > a { background: #FAFAFA; border-left-color: #c4c4c4; }
.snapshots-volume-card.is-locked .snapshots-volume-name,
.snapshots-volume-card.is-locked .snapshots-volume-title { color: #8a8a8a; }
/* Present on every card so the height never depends on lock state; hidden
   rather than removed, which keeps the space and the layout identical. */
.snapshots-volume-locked {
  display: block;
  margin-top: auto;
  padding-top: 6px;
  color: #0048A0;
  font-size: 0.8rem;
  visibility: hidden;
}
.snapshots-volume-card.is-locked .snapshots-volume-locked { visibility: visible; }
@media (min-width: 40rem) {
  .snapshots-volumes { grid-template-columns: 1fr 1fr; }
}
