/* assets/rn/pages/publications.css — /publications.html and /ja/publications.html. Linked LAST, after components.css
   (ja.css follows on /ja/). Publications: everything Tom has published, with the newest first. The page grew out of
   Books & music (janbari-books) and keeps its shelves and their bk- names; what the hub added is named pb-.
   Top to bottom: the hero with an index of the page, the latest books and research, a find box, every book on
   Amazon (a shelf, not a grid of cards: covers at their real proportions stand on a shelf line, and each one rises
   into place from behind it as it arrives), the research at airiskresearch.com as plain dated lists on ink, the
   decoding project, and the music on Spotify.
   Writing family: --rn-signal is yellow (tokens.css), used only for the eyebrow dots, the block behind the H1's last
   word and the band's phrase. No red. Tokens only, no raw colours. Selectors stay at one class and a state or child:
   hover, focus and the entrance reach into a book through custom properties (--bk-*) set on the link or the book.

    1. Hero and the index          5. The lead shelf (stage)      9. Music
    2. Latest                      6. The colouring shelf        10. Closing band
    3. The find box                7. Research                   11. Reduced motion and pause
    4. The shelf (shared)          8. Decoding project           12. Put away by the find box               */

/* 1. Hero ──────────────────────────────────────────────────────────────────────────────────────────────────────
   Work's short hero: eyebrow and the display H1 on the left (its last word lands on the yellow block), the lede and one
   note on the right. The 88px grid is the hero's own, fading out to the right. (This file loads after chrome.css, so
   its padding also replaces chrome.css's phone padding for interior heroes.) */
.bk-hero {
  min-height: 0;
  padding: calc(var(--rn-header-top) + var(--rn-header-h) + clamp(40px, 5.6vw, 80px)) 0 clamp(48px, 5vw, 72px);
  border-bottom: 0;
  background-color: var(--rn-ink);
}

.bk-hero::before {
  opacity: 1;
  background-image: linear-gradient(var(--rn-grid-line) 1px, transparent 1px), linear-gradient(90deg, var(--rn-grid-line) 1px, transparent 1px);
  background-size: var(--rn-grid) var(--rn-grid);
  -webkit-mask-image: linear-gradient(90deg, black 20%, transparent 90%);
  mask-image: linear-gradient(90deg, black 20%, transparent 90%);
}

/* As on Work (work.css 1): the aside sits beside the title while it has 18rem or more, and wraps under it below that. */
.bk-hero-grid {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--rn-space-6) clamp(40px, 6vw, 96px);
}

.bk-hero-title {
  min-width: 0;
}

.bk-hero h1 {
  margin: var(--rn-space-5) 0 0;
  color: var(--rn-text-on-ink);
}

.bk-hero-aside {
  flex: 1 1 18rem;
  max-width: 46ch;
}

.bk-lede {
  margin: 0;
  color: var(--rn-muted-on-ink);
  font: 500 var(--rn-fs-body-lg)/var(--rn-lh-lead) var(--rn-font-body);
}

.bk-note {
  margin: var(--rn-space-5) 0 0;
  padding-top: var(--rn-space-4);
  border-top: 1px solid var(--rn-line-on-ink);
  color: var(--rn-muted-on-ink);
  font: 500 var(--rn-fs-label)/1.5 var(--rn-font-mono);
  letter-spacing: var(--rn-track-label);
  text-transform: uppercase;
}

/* The index: one chip per part of the page, on a row of its own under the title and the lede. Plain anchors (the
   shared rn-chip, 44px tall); html's scroll-padding lands each target clear of the header. */
.pb-index {
  display: flex;
  flex: 1 1 100%;
  flex-wrap: wrap;
  gap: var(--rn-space-2);
}

@media (max-width: 900px) {
  .bk-hero-aside {
    flex-basis: 100%;
  }
}

/* 2. Latest ────────────────────────────────────────────────────────────────────────────────────────────────────
   Two cards on paper, the newest of each kind with its date: books on the left (the covers in miniature beside the
   words; they are the same files the shelves below use, and decorative here, since each book has its own entry with
   its alt text further down), research on the right. A book's line jumps to its entry on the shelf; a research line
   goes to the piece itself. Each card ends with the way to its full list. */
.pb-latest {
  padding-block: clamp(48px, 6vw, 88px) clamp(32px, 4vw, 56px);
  background: var(--rn-paper);
  color: var(--rn-text-on-paper);
}

.pb-latest-grid {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: clamp(16px, 2.2vw, 32px);
}

.pb-new {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  min-width: 0;
  padding: clamp(20px, 2.8vw, 36px) clamp(20px, 2.8vw, 36px) var(--rn-space-4);
  border: 1px solid var(--rn-card-ring);
  border-radius: var(--rn-radius-card);
  background: var(--rn-card-bg);
}

/* The small mono label: a card's kind here, and the find box's label. */
.pb-label {
  margin: 0;
  color: var(--rn-muted);
  font: 500 var(--rn-fs-label)/1.4 var(--rn-font-mono);
  letter-spacing: var(--rn-track-label);
  text-transform: uppercase;
}

.pb-new-list {
  align-self: stretch;
  margin: var(--rn-space-3) 0 var(--rn-space-2);
  padding: 0;
  border-top: 1px solid var(--rn-line);
  list-style: none;
}

.pb-new-item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 6px var(--rn-space-5);
  padding: var(--rn-space-4) 0;
  border-bottom: 1px solid var(--rn-line);
}

.pb-new-item > p {
  grid-column: 1;
  margin: 0;
}

.pb-new-meta {
  color: var(--rn-muted);
  font: 500 var(--rn-fs-label)/1.4 var(--rn-font-mono);
  letter-spacing: var(--rn-track-label);
  text-transform: uppercase;
}

.pb-new-title {
  color: var(--rn-text);
  font: var(--rn-weight-title) var(--rn-fs-title)/var(--rn-lh-title) var(--rn-font-body);
  letter-spacing: var(--rn-track-title);
  text-wrap: balance;
}

/* The link is the title's words; its padding makes the target 44px tall without moving the lines. */
.pb-new-link {
  padding-block: 9px;
  color: inherit;
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
}

.pb-new-link:is(:hover, :focus-visible) {
  text-decoration-thickness: 2px;
}

.pb-new-line {
  color: var(--rn-muted);
  font: 500 var(--rn-fs-small)/1.5 var(--rn-font-body);
}

.pb-thumbs {
  display: flex;
  grid-row: 1 / span 3;
  grid-column: 2;
  align-items: flex-end;
  gap: var(--rn-space-2);
}

.pb-thumbs > img {
  display: block;
  width: auto;
  height: clamp(80px, 7.4vw, 108px);
  border-radius: 2px 4px 4px 2px;
  box-shadow: var(--rn-ring-on-paper);
}

.pb-new > .rn-link {
  margin-top: auto;
}

@media (max-width: 900px) {
  .pb-latest-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 640px) {
  .pb-new-item {
    grid-template-columns: minmax(0, 1fr);
  }

  .pb-thumbs {
    grid-row: auto;
    grid-column: 1;
    margin-top: var(--rn-space-2);
  }
}

/* 3. The find box ──────────────────────────────────────────────────────────────────────────────────────────────
   At the top of the full lists: one underlined field (the brief's field, on paper), its label above and a status line
   under it that says what it does and then how many titles match. It only works with pages/publications.js, so it
   shows only when scripts run (the first head script sets html.js); without them the lists below are all there is
   to need. Its Clear button is put away until something is typed (section 12). */
.pb-find {
  display: none;
  max-width: 40rem;
  margin-bottom: clamp(24px, 3vw, 40px);
}

.js .pb-find {
  display: block;
}

.pb-find-field {
  display: flex;
  margin-top: var(--rn-space-2);
  align-items: center;
  gap: var(--rn-space-4);
}

.pb-find-input {
  flex: 1;
  min-width: 0;
  min-height: 48px;
  margin: 0;
  padding: 10px 0;
  border: 0;
  border-bottom: 1px solid var(--rn-field-line-on-paper);
  border-radius: var(--rn-radius-input);
  background: transparent;
  color: var(--rn-text);
  font: 400 1rem/1.5 var(--rn-font-body);
  appearance: none;
}

.pb-find-input::placeholder {
  color: var(--rn-muted);
  opacity: 1;
}

.pb-find-input::-webkit-search-cancel-button {
  display: none;
}

.pb-find-input:focus {
  border-bottom-color: var(--rn-text);
  box-shadow: 0 1px 0 var(--rn-text);
}

.pb-find-input:focus-visible {
  outline: 2px solid var(--rn-text);
  outline-offset: 4px;
}

.pb-find-status {
  margin: var(--rn-space-2) 0 0;
  color: var(--rn-muted);
  font: 500 var(--rn-fs-small)/1.45 var(--rn-font-body);
}

/* 4. The shelf ─────────────────────────────────────────────────────────────────────────────────────────────────
   An <ol> of books. Each book's title is its link to Amazon, stretched over the whole book (cover and words) by its
   ::after, so the whole book is one target while a screen reader still reads the book's format, lines and cover as
   they are; the cue under it is visual only. A second edition (How To Raise Children's paperback, the prompt guide in
   Hindi) is a second link that sits above the stretch. The cover frame is --bk-h tall and runs the full column, its bottom border the shelf: columns sit
   flush (the gutter is padding inside each column), so the line runs unbroken along a row. Covers keep their own
   proportions and stand on it, bottom-aligned. The frame clips only below the shelf (clip-path), so a cover can rise
   from behind it on arrival and lift above it on hover. Under the shelf: format and year in mono, the title, the
   subtitle, one line on the book, and the cue. */
.bk-shelf {
  --bk-gap: clamp(16px, 2.2vw, 32px);
  --bk-line: var(--rn-line-strong-on-paper);
  --bk-cover-ring: var(--rn-ring-on-paper);
  display: grid;
  margin: 0;
  padding: 0;
  list-style: none;
}

.bk-book {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  min-width: 0;
  color: var(--rn-text);
}

.bk-link {
  color: inherit;
  text-decoration: none;
}

/* The stretch, and the focus ring drawn round the whole book (the link's own ring would circle only the title). A
   book with a second edition leaves that link's row out (--bk-alt-h), so the ring never takes in the other link.
   Columns sit flush and the ring is drawn 4px outside its box, so the box stops half a gutter short of the column's
   right edge: the ring ran over the first letters of the next book. A book's own words end a whole gutter short. */
.bk-link::after {
  content: "";
  position: absolute;
  z-index: 1;
  inset: 0 calc(var(--bk-gap) / 2) var(--bk-alt-h, 0) 0;
  outline: var(--bk-ring, none);
  outline-offset: var(--rn-focus-offset);
  box-shadow: var(--bk-band, none);
}

/* The words come first in the source (the title, then what the book is); the cover still shows first. */
.bk-cover {
  order: -1;
  display: flex;
  align-items: flex-end;
  height: var(--bk-h);
  margin: 0;
  padding-right: var(--bk-gap);
  border-bottom: 1px solid var(--bk-line);
  clip-path: inset(-40px -40px 0 -40px);
}

.bk-cover > img {
  display: block;
  width: var(--bk-img-w, auto);
  height: var(--bk-img-h, 100%);
  border-radius: 2px 5px 5px 2px;
  box-shadow: var(--bk-cover-ring);
  translate: 0 var(--bk-lift, 0);
  transition: translate var(--rn-dur-ui) var(--rn-ease-ui);
  animation: var(--bk-shelve, none) var(--rn-dur-ui) var(--rn-ease-ui) backwards; /* the entrance: section 11 */
  animation-delay: calc(min(var(--reveal-i, 0), 5) * var(--rn-stagger) * 2 + var(--rn-delay, 0ms));
}

.bk-info {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 6px;
  padding: var(--rn-space-5) var(--bk-gap) 0 0;
}

.bk-meta {
  order: -1;
  margin: 0 0 2px;
  color: var(--rn-muted);
  font: 500 var(--rn-fs-label)/1.4 var(--rn-font-mono);
  letter-spacing: var(--rn-track-label);
  text-transform: uppercase;
}

/* Each part of the meta line (format, year, language) stays whole, its dot with it, so a narrow column breaks between
   parts and never inside ヒンディー語 or after a dot. An age range ("Ages 4-8") or 第1巻 stays whole the same way. */
.bk-meta > span,
.bk-nobr {
  white-space: nowrap;
}

.bk-title {
  margin: 0;
  color: var(--rn-text);
  font: var(--rn-weight-title) var(--bk-title-size, var(--rn-fs-title))/var(--bk-title-lh, var(--rn-lh-title)) var(--rn-font-body);
  letter-spacing: var(--bk-title-track, var(--rn-track-title));
  text-wrap: balance;
}

/* A subtitle never ends on one word ("Costume / Adventures"): its last two words are joined in the markup. */
.bk-sub {
  margin: 0;
  color: var(--rn-text);
  font: var(--bk-sub-weight, 600) var(--rn-fs-small)/1.45 var(--rn-font-body);
  text-wrap: pretty;
}

.bk-desc {
  margin: 4px 0 0;
  color: var(--rn-muted);
  font: 500 var(--rn-fs-small)/1.55 var(--rn-font-body);
  text-wrap: pretty;
}

/* The cue sits at the foot of the column, so a row's cues line up. */
.bk-cue {
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  gap: 9px;
  min-height: var(--rn-target);
  margin-top: auto;
  padding-top: var(--rn-space-2);
  font: 700 var(--rn-fs-small)/1.2 var(--rn-font-body);
  text-decoration-line: underline;
  text-decoration-thickness: var(--bk-cue-line, 1px);
  text-underline-offset: 4px;
  transition: text-decoration-thickness var(--rn-dur-snap) var(--rn-ease-snap);
}

.bk-cue > span {
  display: inline-block;
  translate: var(--bk-nudge, 0 0);
  transition: translate var(--rn-dur-snap) var(--rn-ease-snap);
}

.bk-book:hover {
  --bk-cue-line: 2px;
}

.bk-link:focus-visible {
  --bk-ring: var(--rn-focus-outline);
  --bk-band: var(--rn-focus-band);
  outline: 0;
  box-shadow: none;
}

/* The second edition's link under the cue, above the stretch. */
.bk-alt {
  position: relative;
  z-index: 2;
  align-self: flex-start;
}

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .bk-book:hover {
    --bk-lift: -6px;
    --bk-nudge: 3px -3px;
  }
}

/* 5. The lead shelf ────────────────────────────────────────────────────────────────────────────────────────────
   The shared feature surface (rn-feature: stage ink, the 88px grid, the ring, radius 20) as one block: the heading and
   the author-page link across the top, then the eight written books, newest first, three to a shelf, the covers tall
   (about 350px at 1440) so they read as the page's feature. The three Japanese, Osaka Style books share the newest
   date, so the series stands together on the first shelf. Three across down to 641px; on a phone one to a shelf,
   still standing on it, the covers 320px tall (half again the colouring covers) and a clear gap between books, wider
   than any gap inside one. Two books have a second link (the paperback, the Hindi edition) under their cue, so the
   others keep that row free and every cue on a shelf lines up. The section is its own formatting context: with no
   bottom padding, a search that puts the whole stage away let the find box's bottom margin through, and main's ink
   showed as a band between this paper and the colouring shelf's. */
.bk-books {
  display: flow-root;
  padding-block: clamp(16px, 2.8vw, 40px) 0;
  background: var(--rn-paper);
  color: var(--rn-text-on-paper);
}

.bk-stage {
  display: block;
  padding: clamp(24px, 4.4vw, 64px);
  background-position: -1px -1px;
}

.bk-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--rn-space-4) var(--rn-space-6);
  margin-bottom: clamp(32px, 4vw, 56px);
}

.bk-head h2 {
  margin: var(--rn-space-4) 0 0;
  color: var(--rn-text);
  font: var(--rn-weight-display) var(--rn-fs-h2)/var(--rn-lh-heading) var(--rn-font-display);
  letter-spacing: var(--rn-track-display);
}

.bk-shelf.bk-lead {
  --bk-h: clamp(300px, 25vw, 352px);
  --bk-line: var(--rn-muted-on-ink);
  --bk-cover-ring: var(--rn-ring-on-ink);
  grid-template-columns: repeat(3, minmax(0, 1fr));
  row-gap: clamp(40px, 4.4vw, 64px);
}

.bk-lead > .bk-book {
  padding-bottom: var(--rn-target); /* the second-edition link's row */
}

.bk-book.bk-has-alt {
  --bk-alt-h: var(--rn-target);
  padding-bottom: 0;
}

@media (max-width: 900px) {
  .bk-shelf.bk-lead {
    --bk-h: clamp(240px, 35vw, 300px);
  }
}

@media (max-width: 640px) {
  .bk-shelf.bk-lead {
    --bk-h: 320px;
    grid-template-columns: minmax(0, 1fr);
    row-gap: clamp(48px, 14vw, 64px);
  }

  .bk-lead > .bk-book {
    padding-bottom: 0;
  }
}

/* 6. The colouring shelf ───────────────────────────────────────────────────────────────────────────────────────
   Ten on paper, newest first: five to a shelf while the shelf is 47.5rem wide or more (a screen of about 800px), so
   the ten read as two full shelves on a tablet as on desktop, and two to a shelf below that (only counts that divide
   ten, so no shelf is left part empty). Five across a narrower shelf set the titles on four or five lines in 120 to
   146px columns. The switch is the shelf's own width (100cqi of its container), not a breakpoint: --bk-two is
   positive only under 47.5rem, where it lifts the column's minimum from 18cqi (five fit) to 40cqi (two fit) and the
   cover to 190px. That is an enhancement inside @supports: a browser without container units keeps five across down
   to 641px, as before. (As a second declaration after the plain one it was no fallback: with var() in it, every
   browser accepts it when parsing, and one that does not know cqi then drops to one book a row.)
   The covers stay smaller than the lead shelf's at every width. The heading and one line on the set sit above; the
   titles step down to body size (they are long, and there are ten). At 900px and below the one-line descriptions go:
   the title and subtitle already say what each book is, and in narrow columns ten of them made a wall of small text. */
.bk-colouring {
  padding-block: clamp(64px, 8vw, 120px) var(--rn-section-tight);
  background: var(--rn-paper);
  color: var(--rn-text-on-paper);
}

.bk-section-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 44ch);
  align-items: end;
  gap: var(--rn-space-5) clamp(32px, 5vw, 80px);
  margin-bottom: clamp(32px, 4vw, 56px);
}

/* Research and the decoding project say more beside their heading: the words get the wider column, from the top. */
.pb-wide {
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  align-items: start;
}

.bk-section-head h2 {
  margin: var(--rn-space-4) 0 0;
  color: var(--rn-text);
}

.bk-section-head > p {
  margin: 0;
  color: var(--rn-muted);
  font: 500 var(--rn-fs-body-lg)/var(--rn-lh-lead) var(--rn-font-body);
}

.bk-colouring > .studio-container {
  container-type: inline-size;
}

.bk-shelf.bk-small {
  --bk-h: clamp(180px, 14.5vw, 216px);
  --bk-title-size: var(--rn-fs-body);
  --bk-title-lh: 1.3;
  --bk-title-track: 0;
  --bk-sub-weight: 500;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  row-gap: clamp(40px, 4vw, 56px);
}

@media (max-width: 900px) {
  .bk-section-head {
    grid-template-columns: minmax(0, 1fr);
  }

  .bk-shelf.bk-small {
    --bk-h: clamp(130px, 21vw, 190px);
  }

  .bk-small .bk-desc {
    display: none;
  }
}

@supports (width: 1cqi) {
  .bk-shelf.bk-small {
    --bk-two: calc((47.5rem - 100cqi) * 999);
    grid-template-columns: repeat(auto-fill, minmax(max(18cqi, min(40cqi, var(--bk-two))), 1fr));
  }

  @media (max-width: 900px) {
    .bk-shelf.bk-small {
      --bk-h: max(clamp(130px, 21vw, 190px), min(190px, var(--bk-two)));
    }
  }
}

@media (max-width: 640px) {
  .bk-shelf.bk-small {
    --bk-h: 172px;
    --bk-gap: 16px;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* 7. Research ──────────────────────────────────────────────────────────────────────────────────────────────────
   AI Risk Research, on ink so it reads as a different kind of work from the shelves: what the project is, in Tom's
   words, then the nine feature pages as a three-column list (title and one line each), then the dated lists. The
   Land Wars reports and the daily briefs share the narrower column, the tracker's long headlines take the wider one.
   A list shows its latest five; the rest sit in a native <details> right under them, so the whole record is on the
   page and one tap away, and the find box opens whichever holds a match. No cards and no motion of their own: rows
   on hairlines, each one a date and a link. */
.pb-research {
  padding-block: var(--rn-section-tight);
  background: var(--rn-ink);
  color: var(--rn-text-on-ink);
}

.pb-research-intro > p {
  max-width: var(--rn-measure);
  margin: 0 0 var(--rn-space-3);
  color: var(--rn-muted);
  font: 500 var(--rn-fs-body-lg)/var(--rn-lh-lead) var(--rn-font-body);
}

.pb-block {
  margin-top: clamp(32px, 4vw, 56px);
}

.pb-h3 {
  margin: 0;
  color: var(--rn-text);
  font: var(--rn-weight-title) var(--rn-fs-title)/var(--rn-lh-title) var(--rn-font-body);
  letter-spacing: var(--rn-track-title);
}

.pb-block-note {
  max-width: var(--rn-measure);
  margin: var(--rn-space-2) 0 0;
  color: var(--rn-muted);
  font: 500 var(--rn-fs-small)/1.55 var(--rn-font-body);
}

.pb-features {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0 clamp(24px, 3vw, 48px);
  margin: var(--rn-space-4) 0 0;
  padding: 0;
  list-style: none;
}

.pb-feature {
  padding: var(--rn-space-4) 0 var(--rn-space-5);
  border-top: 1px solid var(--rn-line);
}

.pb-feature > p {
  margin: var(--rn-space-2) 0 0;
  color: var(--rn-muted);
  font: 500 var(--rn-fs-small)/1.55 var(--rn-font-body);
}

.pb-feature-link {
  padding-block: 10px;
  color: var(--rn-text);
  font: 700 var(--rn-fs-body-lg)/1.4 var(--rn-font-body);
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
}

.pb-feature-link:is(:hover, :focus-visible) {
  text-decoration-thickness: 2px;
}

/* Flex, not a grid: when the find box puts one column away, the other takes the whole width. */
.pb-lists {
  display: flex;
  align-items: flex-start;
  gap: 0 clamp(32px, 5vw, 80px);
}

.pb-col {
  flex: 5 1 0;
  min-width: 0;
}

.pb-col-wide {
  flex: 7 1 0;
  min-width: 0;
}

/* A dated list. The link carries the row's padding, so the whole line beside the date is the target (45px or more). */
.pb-rows {
  margin: var(--rn-space-4) 0 0;
  padding: 0;
  border-top: 1px solid var(--rn-line);
  list-style: none;
}

.pb-row {
  display: grid;
  grid-template-columns: 6.5rem minmax(0, 1fr);
  align-items: baseline;
  column-gap: var(--rn-space-4);
  border-bottom: 1px solid var(--rn-line);
}

.pb-date {
  color: var(--rn-muted);
  font: 500 var(--rn-fs-label)/1.4 var(--rn-font-mono);
  letter-spacing: var(--rn-track-label);
  text-transform: uppercase;
  white-space: nowrap;
}

.pb-row-link {
  display: block;
  padding-block: 11px;
  color: var(--rn-text);
  font: 500 var(--rn-fs-body)/1.45 var(--rn-font-body);
  text-decoration: none;
}

.pb-row-link:is(:hover, :focus-visible) {
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
}

/* The earlier ones: a native disclosure, a plus that reads as a minus when open (as on the FAQs, without the turn).
   The summary reaches 8px past the column on each side, so the focus ring clears the label while the words and the
   plus stay where they were. */
.pb-more {
  border-bottom: 1px solid var(--rn-line);
}

.pb-more > summary {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 52px;
  margin-inline: -8px;
  padding-inline: 8px 52px;
  color: var(--rn-text);
  font: 700 var(--rn-fs-body)/1.3 var(--rn-font-body);
  list-style: none;
  cursor: pointer;
}

.pb-more > summary::-webkit-details-marker {
  display: none;
}

.pb-more > summary::before,
.pb-more > summary::after {
  position: absolute;
  top: 50%;
  right: 16px;
  width: 14px;
  height: 2px;
  margin-top: -1px;
  border-radius: 1px;
  background: currentColor;
  content: "";
}

.pb-more > summary::after {
  transform: var(--pb-plus, rotate(90deg));
}

.pb-more[open] {
  --pb-plus: none;
}

/* The earlier briefs differ only by their date, so they are a grid of dates rather than 32 rows of the same words. */
.pb-days {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
  gap: 0 var(--rn-space-4);
  margin: 0 0 var(--rn-space-3);
  padding: 0;
  border-top: 1px solid var(--rn-line);
  list-style: none;
}

.pb-day {
  display: flex;
  align-items: center;
  min-height: var(--rn-target);
  color: var(--rn-text);
  font: 500 var(--rn-fs-small)/1.3 var(--rn-font-body);
  font-variant-numeric: tabular-nums;
  text-decoration: none;
}

.pb-day:is(:hover, :focus-visible) {
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
}

.pb-langs {
  max-width: var(--rn-measure);
  margin: clamp(32px, 4vw, 56px) 0 0;
  color: var(--rn-muted);
  font: 500 var(--rn-fs-small)/1.55 var(--rn-font-body);
}

@media (max-width: 900px) {
  .pb-features {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .pb-lists {
    flex-direction: column;
    align-items: stretch;
  }
}

/* On a phone a row is its date, then its title under it. */
@media (max-width: 640px) {
  .pb-features {
    grid-template-columns: minmax(0, 1fr);
  }

  .pb-row {
    grid-template-columns: minmax(0, 1fr);
    padding-top: var(--rn-space-3);
  }

  .pb-row-link {
    padding-block: 2px var(--rn-space-3);
  }
}

/* 8. Decoding projects ─────────────────────────────────────────────────────────────────────────────────────────
   The heading, what the project is in Tom's words, and the cipher-letter pages under /decoding/ (standalone pages
   from the research project, 3 Oct 2026): the feature-list pattern from the research band, on paper, and one note. */
/* flow-root: the head's bottom margin stays inside the paper (it collapsed through and showed the page's ink). */
.pb-decoding {
  display: flow-root;
  padding-top: var(--rn-section-tight);
  background: var(--rn-paper);
  color: var(--rn-text-on-paper);
}

.pb-dec-block {
  margin-top: var(--rn-space-6);
}

.pb-dec-note {
  max-width: var(--rn-measure);
  margin: var(--rn-space-2) 0 0;
  color: var(--rn-muted);
  font: 500 var(--rn-fs-small)/1.55 var(--rn-font-body);
}

/* 9. Music ─────────────────────────────────────────────────────────────────────────────────────────────────────
   The Spotify page in words and one button (no player: the page loads nothing from Spotify), the latest releases as a
   short list, and Render Distance as an ink card with its tracklist and the game behind each track. The card simply
   rises in (data-rn-reveal): fifteen rows landing one by one would still be moving below the fold on a phone. */
.bk-music {
  padding-block: var(--rn-section-tight) var(--rn-section);
  background: var(--rn-paper);
  color: var(--rn-text-on-paper);
}

.bk-music-grid {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  align-items: start;
  gap: var(--rn-space-7) clamp(32px, 5vw, 80px);
}

.bk-music-copy {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--rn-space-4);
  min-width: 0;
}

.bk-music-copy > h2 {
  margin: 0 0 var(--rn-space-2);
  color: var(--rn-text);
}

.bk-para {
  max-width: 46ch;
  margin: 0;
  color: var(--rn-muted);
  font: 500 var(--rn-fs-body-lg)/var(--rn-lh-lead) var(--rn-font-body);
}

.bk-music-copy > .rn-actions {
  margin-top: var(--rn-space-2);
}

.bk-latest {
  align-self: stretch;
  margin-top: var(--rn-space-5);
}

.bk-latest h3 {
  margin: 0 0 var(--rn-space-3);
  color: var(--rn-muted);
  font: 500 var(--rn-fs-label)/1.4 var(--rn-font-mono);
  letter-spacing: var(--rn-track-label);
  text-transform: uppercase;
}

.bk-latest ul {
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--rn-line);
  list-style: none;
}

.bk-latest li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--rn-space-4);
  border-bottom: 1px solid var(--rn-line);
}

.bk-latest .rn-link {
  font-size: var(--rn-fs-body);
}

.bk-latest li > span {
  color: var(--rn-muted);
  font: 500 var(--rn-fs-label)/1.4 var(--rn-font-mono);
  letter-spacing: var(--rn-track-label);
  text-transform: uppercase;
}

/* Render Distance: an ink card on the paper section (the feature's stage and grid at card scale). */
.bk-album {
  --rn-text: var(--rn-text-on-ink);
  --rn-muted: var(--rn-muted-on-ink);
  --rn-line: var(--rn-line-on-ink);
  --rn-on-text: var(--rn-ink);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--rn-space-3);
  min-width: 0;
  padding: clamp(24px, 3.4vw, 48px);
  border: 1px solid var(--rn-ring);
  border-radius: var(--rn-radius-card);
  background-color: var(--rn-stage);
  background-image: linear-gradient(var(--rn-grid-line) 1px, transparent 1px), linear-gradient(90deg, var(--rn-grid-line) 1px, transparent 1px);
  background-size: var(--rn-grid) var(--rn-grid);
  background-position: -1px -1px;
  color: var(--rn-text);
}

.bk-album-kicker {
  margin: 0;
  color: var(--rn-muted);
  font: 500 var(--rn-fs-label)/1.4 var(--rn-font-mono);
  letter-spacing: var(--rn-track-label);
  text-transform: uppercase;
}

.bk-album > h3 {
  margin: 0;
  color: var(--rn-text);
  font: var(--rn-weight-display) var(--rn-fs-h2-sm)/var(--rn-lh-heading) var(--rn-font-display);
  letter-spacing: var(--rn-track-display);
}

.bk-album-line {
  max-width: 48ch;
  margin: 0;
  color: var(--rn-muted);
  font: 500 var(--rn-fs-body)/var(--rn-lh-body) var(--rn-font-body);
}

/* Fifteen rows in two columns (read down, then across); one column on a phone. */
.bk-tracks {
  display: grid;
  grid-template-rows: repeat(8, auto);
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-auto-flow: column;
  column-gap: var(--rn-space-6);
  align-self: stretch;
  margin: var(--rn-space-3) 0 var(--rn-space-2);
  padding: 0;
  list-style: none;
}

/* align-content: start keeps a row's two lines together when the row beside it runs to three. */
.bk-tracks > li {
  display: grid;
  grid-template-columns: 2.4em minmax(0, 1fr);
  align-content: start;
  align-items: baseline;
  padding: 9px 0;
  border-top: 1px solid var(--rn-line);
}

.bk-tr-n {
  grid-row: span 2;
  color: var(--rn-muted);
  font: 500 var(--rn-fs-label)/1.5 var(--rn-font-mono);
  letter-spacing: var(--rn-track-label);
}

.bk-tr-t {
  color: var(--rn-text);
  font: 600 var(--rn-fs-small)/1.35 var(--rn-font-body);
}

.bk-tr-g {
  color: var(--rn-muted);
  font: 500 var(--rn-fs-small)/1.35 var(--rn-font-body);
}

@media (max-width: 900px) {
  .bk-music-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 640px) {
  .bk-tracks {
    grid-template-rows: none;
    grid-template-columns: minmax(0, 1fr);
    grid-auto-flow: row;
  }
}

/* 10. Closing band: the shared rn-band, straight after the paper music section (no second gap above the card). */
.studio-publications-page .rn-band {
  padding-top: 0;
}

/* 11. Reduced motion and pause ──────────────────────────────────────────────────────────────────────────────────
   Each book fades in as it arrives (data-rn-reveal="fade"; motion.js adds .is-visible), and its cover rises from
   behind the shelf on the UI spring, a quarter beat after the one before it (books arriving together: six steps at
   most). The words under the shelf are their own reveal (data-rn-reveal on .bk-info): they rise in when they
   themselves come into view, so they never play out below the fold under a cover that has already arrived. The book
   names the cover's animation in a custom property once it is visible, so the rules stay one class deep. Never under
   reduced motion (the name is only set without it), never while paused or after the 4s failsafe has shown the book
   (.rn-shown): the name goes back to none, and the books simply stand on the shelf. */
@media (prefers-reduced-motion: no-preference) {
  .bk-book.is-visible {
    --bk-shelve: bk-shelve;
  }
}

.bk-book.rn-shown,
[data-motion="paused"] .bk-book {
  --bk-shelve: none;
}

@keyframes bk-shelve {
  from {
    translate: 0 101%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .bk-cover > img,
  .bk-cue,
  .bk-cue > span {
    transition: none;
  }
}

/* 12. Put away by the find box ─────────────────────────────────────────────────────────────────────────────────
   pages/publications.js gives this to a title that does not match, to a list left with none, and to its own Clear
   button while the box is empty. Last in the file, so it wins over each thing's own display at the same weight. */
.pb-off {
  display: none;
}
