/* =====================================================================
   THE LIBRARY — its own sheet, scoped under `.alv-lib`.

   Built from docs/college/new-page-design/Alvara_The_Library.html. Like the
   front page, and unlike the Fellows/College/Membership set, it does not load
   alvara-editorial.css: its hero is its own (it was excepted from the one-hero
   rule deliberately), and so is the left-hand rail, the paper spreads and the
   entry index. One page, one sheet.

   `overflow-x` is `clip` rather than the mockup's `hidden`: on a wrapper,
   `hidden` computes the other axis to `auto` and gives the page a second
   scrollbar inside the content. See the same note in alvara-editorial.css.

   Two things this sheet expects of the markup, because they are what make the
   page work rather than what makes it look right:

   - `.page` carries `margin-left: var(--rail)` above 1200px, which is what
     holds the content clear of the fixed rail. The rail is inside the scoped
     wrapper, so it is styled here; it is `position:fixed`, whose containing
     block is the viewport and which `overflow: clip` does not clip.
   - `.lib-entry.is-hidden` is what the search box sets. Filtering hides
     server-rendered rows rather than building a list, so the index is whole
     and correct with JavaScript off and the filter is what is added on top —
     the same arrangement the reader's Branch Navigator uses.
   ===================================================================== */

/* The page's own paper palette used to stand here -- `--ink` #25321d,
   `--ink-soft` rgba(37,50,29,.74), `--ink-faint` .5, `--paper-rule` .28,
   `--ivory` #ece4d1. Four of those five are the ground contract's light
   values said again (`--ivory` IS `--sec-ground`, `--paper-rule` IS
   `--ground-hair`), and the two inks are the readings main.css settled
   AGAINST: #25321d for both heading and prose, where the estate reads #20301a
   over #39402d so a long measure does not sit as heavy as its own heading.

   So the paper sections take the contract below and every rule here reads
   `--ground-*`. `--rail` is the page's own and stays. */
.alv-lib {
  --rail: 256px;

  /* ===== THE MEASURE =====
     One reading width for the Library. There were four: the article at a flat
     760px, a hub's sections at 68ch, its lede at 64ch and the entry
     descriptions at 66ch — so the same prose changed width depending on which
     kind of page it was on, and none of them was the estate's own.

     74ch is `.alv-ed .body`, which is what every other text block on the site
     is set to. Widening past it is a typographic decision rather than a
     layout one: much beyond 75 characters the eye starts losing the line
     return. This is the one place to change it.

     ===== THE GUTTER =====
     `clamp(24px, 5vw, 80px)` measured 5% of the VIEWPORT, and the Library's
     wraps sit inside a column the rails have already taken 556px out of. So a
     1440px window put a 72px gutter inside an 869px column — a full-width
     page's margin applied to something that is not full width. The gutter
     steps down where the rails appear. */
  --measure: 74ch;
  --gutter: clamp(24px, 5vw, 80px);
}

@media (min-width: 1200px) {
  .alv-lib {
    --gutter: clamp(24px, 2.6vw, 48px);
  }
}

.alv-lib * {
  margin: 0;
  padding: 0;
  box-sizing: border-box
}

.alv-lib {
  scroll-behavior: smooth
}

.alv-lib {
  font-family: var(--body);
  color: var(--cream);
  -webkit-font-smoothing: antialiased;
  font-size: var(--fs-body-lg);
  line-height: calc(1.6 * var(--lh-scale));
  overflow-x: clip;
  position: relative;
  background-color: var(--g3)
}

.alv-lib a {
  color: inherit;
  text-decoration: none
}

.alv-lib img {
  display: block;
  max-width: 100%
}

/* 1200px, which is the estate's measure. This sheet said 1180 and the
   editorial one 1200, so the Library's content column stood 20px narrower
   than every other page's for no reason anybody chose. */
.alv-lib .wrap {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 var(--gutter);
  position: relative
}

.alv-lib .reveal {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity .8s cubic-bezier(.2, .6, .2, 1), transform .8s cubic-bezier(.2, .6, .2, 1)
}

.alv-lib .reveal.in {
  opacity: 1;
  transform: none
}

/* ===================== Library rail (desktop) ===================== */
.alv-lib .libnav {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: var(--rail);
  z-index: 70;
  background: #0b1d13;
  border-right: 1px solid var(--gold-line);
  padding: 96px 26px 24px;
  /* Off by default and turned on at 1200px, where `.page` gains the matching
     `margin-left` to clear it. The rail is `position:fixed`, so shown below
     that width it would stand over the content rather than beside it. */
  display: none;
  flex-direction: column
}

.alv-lib .libnav-head {
  display: flex;
  align-items: center;
  gap: 12px;
  text-decoration: none;
  padding-bottom: 18px;
  border-bottom: 1px solid rgba(242, 237, 224, .09)
}

.alv-lib .libnav-head img {
  width: 38px;
  height: 38px;
  opacity: .92;
  border-radius: 50%
}

/* One line beside the seal, so `align-items: center` on the head above is what
   sets it against the middle of the mark. It used to sit over a second line
   reading "Alvará", which the masthead two rows up already says. */
.alv-lib .libnav-head .rt {
  font-family: var(--word);
  font-size: var(--fs-body-sm);
  letter-spacing: .12em;
  color: var(--cream);
  line-height: 1.1;
  transition: color .3s
}

.alv-lib .libnav-head:hover .rt {
  color: var(--gold-soft)
}

.alv-lib .libnav-head:focus-visible {
  outline: 2px solid var(--gold-soft);
  outline-offset: 3px
}

/* The rail now carries all twenty-nine entries under their three Branches, so
   it is the one thing on the page that has to scroll inside itself. `min-height:0`
   is what lets a flex child shorter than its content actually shrink — without
   it the list takes its content height, pushes the foot off the bottom of a
   fixed rail, and nothing scrolls anywhere. */
.alv-lib .libnav-list {
  margin-top: 22px;
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--gold-line) transparent
}

/* THE RAIL IS READABLE AT REST, AND HOVER ONLY DECORATES IT.
   ------------------------------------------------------------------
   The contents used to sit at 50% and 42% cream and come up to full on hover,
   which is a design for a mouse: an iPad has no hover state to give, so the
   whole table of contents stayed at its dimmest for the entire visit, and the
   one moment it did brighten was the tap that navigated away from it.

   So the resting colours are the reading colours — the Branch rows at .88 and
   their entries a step below at .72, which keeps the hierarchy without making
   either of them hard to read. What hover adds is an underline, and it is
   declared inside `@media (hover: hover) and (pointer: fine)` so a touch device
   is never offered it. `hover: hover` alone is not enough: a stylus and some
   hybrid laptops report it while reporting a coarse pointer, and the underline
   then flickers under a finger. */
.alv-lib .libnav-list a,
.alv-lib .libnav-list summary {
  display: flex;
  gap: 13px;
  align-items: baseline;
  font-family: var(--body);
  font-size: var(--fs-note);
  color: rgba(242, 237, 224, .88);
  padding: 11px 0;
  transition: color .3s;
  position: relative;
  text-decoration-color: transparent;
  text-underline-offset: 3px
}

.alv-lib .libnav-list .rn {
  font-family: var(--word);
  font-size: var(--fs-micro);
  letter-spacing: .1em;
  color: var(--gold);
  width: 26px;
  flex: none
}

.alv-lib .libnav-list .rl {
  line-height: 1.25;
  flex: 1
}

@media (hover: hover) and (pointer: fine) {
  .alv-lib .libnav-list a:hover,
  .alv-lib .libnav-list summary:hover {
    color: var(--cream);
    text-decoration: underline;
    text-decoration-color: var(--gold-soft)
  }

  .alv-lib .libnav-sub a:hover {
    color: var(--cream);
    text-decoration: underline;
    text-decoration-color: var(--gold-soft)
  }

  .alv-lib .libnav-sub a:hover .sn {
    color: var(--gold-soft)
  }

  .alv-lib .libnav-m .mlist a:hover {
    color: var(--cream);
    text-decoration: underline;
    text-decoration-color: var(--gold-soft)
  }
}

/* Keyboard focus is not hover and is not gated by it: a rail reached by Tab has
   to show where it is on every device. */
.alv-lib .libnav-list a:focus-visible,
.alv-lib .libnav-list summary:focus-visible,
.alv-lib .libnav-sub a:focus-visible,
.alv-lib .libnav-m .mlist a:focus-visible {
  outline: 2px solid var(--gold-soft);
  outline-offset: 2px;
  color: var(--cream)
}

.alv-lib .libnav-list .active {
  color: var(--cream)
}

.alv-lib .libnav-list .active::before {
  content: "";
  position: absolute;
  left: -26px;
  top: 6px;
  bottom: 6px;
  width: 2px;
  background: var(--gold-soft)
}

.alv-lib .libnav-list .active .rn {
  color: var(--gold-soft)
}

/* ---- the Branch row, and its entries beneath ---- */
.alv-lib .libnav-branch summary {
  cursor: pointer;
  list-style: none
}

.alv-lib .libnav-branch summary::-webkit-details-marker {
  display: none
}

.alv-lib .libnav-branch summary .chev {
  font-size: var(--fs-eyebrow-sm);
  color: var(--gold);
  opacity: .6;
  flex: none;
  transition: transform .3s
}

.alv-lib .libnav-branch[open] summary .chev {
  transform: rotate(180deg)
}

/* Inset, so the entries read as belonging to the Branch above rather than as
   more Branches. The hairline is what carries the eye down the run — the same
   device the reader's own index uses. */
.alv-lib .libnav-sub {
  margin: 0 0 6px 26px;
  padding-left: 14px;
  border-left: 1px solid rgba(242, 237, 224, .09)
}

.alv-lib .libnav-sub a {
  display: flex;
  gap: 10px;
  align-items: baseline;
  font-family: var(--body);
  font-size: var(--fs-meta-alt);
  line-height: 1.35;
  color: rgba(242, 237, 224, .72);
  padding: 6px 0;
  transition: color .25s;
  text-decoration-color: transparent;
  text-underline-offset: 3px
}

.alv-lib .libnav-sub a .sn {
  font-family: var(--word);
  font-size: var(--fs-eyebrow-sm);
  letter-spacing: .08em;
  color: rgba(184, 150, 46, .85);
  width: 18px;
  flex: none
}

.alv-lib .libnav-foot {
  margin-top: 14px;
  padding-top: 16px;
  border-top: 1px solid rgba(242, 237, 224, .09);
  font-family: var(--word);
  font-size: var(--fs-eyebrow-sm);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: rgba(242, 237, 224, .4);
  line-height: 1.5
}

@media(min-width:1200px) {
  .alv-lib .libnav {
    display: flex
  }

  .alv-lib .page {
    margin-left: var(--rail)
  }
}

/* mobile Library selector */
.alv-lib .libnav-m {
  display: block;
  position: sticky;
  top: 76px;
  z-index: 40;
  background: rgba(11, 29, 19, .97);
  border-bottom: 1px solid var(--gold-line);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px)
}

.alv-lib .libnav-m > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 13px clamp(24px, 5vw, 40px);
  font-family: var(--word);
  font-size: var(--fs-eyebrow);
  letter-spacing: .24em;
  text-transform: uppercase;
  color: var(--gold-soft)
}

.alv-lib .libnav-m > summary::-webkit-details-marker {
  display: none
}

.alv-lib .libnav-m > summary .chev {
  transition: transform .3s;
  color: var(--gold)
}

/* `> summary`, not `summary`: the pillars nested in this panel have summaries
   of their own, and unscoped this turned every chevron in the panel the moment
   the panel opened — so a shut pillar pointed up. */
.alv-lib .libnav-m[open] > summary .chev {
  transform: rotate(180deg)
}

.alv-lib .libnav-m .mlist {
  padding: 2px clamp(24px, 5vw, 40px) 14px;
  display: flex;
  flex-direction: column;
  gap: 2px
}

/* The narrow-screen list, which is the one an iPad in portrait actually gets —
   the fixed rail is off below 1200px. Same rule as the rail: readable at rest,
   the underline reserved for a pointer that can hover. */
.alv-lib .libnav-m .mlist a {
  display: flex;
  gap: 12px;
  align-items: baseline;
  padding: 9px 0;
  color: rgba(242, 237, 224, .88);
  font-size: var(--fs-ui);
  border-top: 1px solid rgba(242, 237, 224, .08);
  text-decoration-color: transparent;
  text-underline-offset: 3px
}

.alv-lib .libnav-m .mlist a .rn {
  font-family: var(--word);
  color: var(--gold);
  font-size: var(--fs-label);
  width: 24px
}

/* A pillar in the narrow list, and the articles under it.

   The row is the rail's: a numeral, the pillar's name as a link to its hub,
   and a chevron at the far end that turns with the group. The whole row
   toggles — a `<summary>` does, and the link inside it still navigates — so
   the chevron says what the row does rather than being the only thing that
   does it. A thumb that lands beside the name opens the articles instead of
   missing.

   `list-style: none` and the `::-webkit-details-marker` rule again because
   this is a second `<summary>` inside the first, and the browser's own
   triangle would sit in front of the numeral. */
.alv-lib .libnav-m .mgroup > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  gap: 12px;
  align-items: center;
  padding: 11px 0;
  border-top: 1px solid rgba(242, 237, 224, .08);
  font-family: var(--body);
  font-size: var(--fs-ui);
  color: rgba(242, 237, 224, .88);
}

.alv-lib .libnav-m .mgroup > summary::-webkit-details-marker {
  display: none;
}

.alv-lib .libnav-m .mgroup > summary .rn {
  font-family: var(--word);
  font-size: var(--fs-label);
  color: var(--gold);
  width: 24px;
  flex: none;
}

/* The name takes the row's width so the chevron is pushed to the far end, and
   it is the link — everything either side of it is the toggle. */
.alv-lib .libnav-m .mgroup > summary .rl {
  flex: 1;
  color: inherit;
  text-decoration-color: transparent;
  text-underline-offset: 3px;
}

.alv-lib .libnav-m .mgroup > summary .rl.is-here {
  color: var(--cream);
}

/* 44px of target, which is the smallest a finger can be asked to find, made
   out of padding so the mark itself stays the size it is drawn. */
.alv-lib .libnav-m .mgroup > summary .chev {
  flex: none;
  width: 44px;
  margin: -11px -12px -11px 0;
  padding: 11px 12px;
  text-align: right;
  color: var(--gold);
  transition: transform .3s;
}

.alv-lib .libnav-m .mgroup[open] > summary .chev {
  transform: rotate(180deg);
}

/* The articles, set in from the numeral against a hairline — the rail's
   `.libnav-sub` at the sizes this panel uses. */
.alv-lib .libnav-m .msub {
  margin: 0 0 8px 24px;
  padding-left: 14px;
  border-left: 1px solid rgba(242, 237, 224, .09);
}

.alv-lib .libnav-m .msub a {
  display: flex;
  gap: 10px;
  align-items: baseline;
  padding: 9px 0;
  border-top: 0;
  font-family: var(--body);
  font-size: var(--fs-meta-alt);
  line-height: 1.35;
  color: rgba(242, 237, 224, .72);
}

.alv-lib .libnav-m .msub a.is-here {
  color: var(--cream);
}

.alv-lib .libnav-m .msub a .sn {
  font-family: var(--word);
  font-size: var(--fs-eyebrow-sm);
  letter-spacing: .08em;
  color: rgba(184, 150, 46, .85);
  width: 18px;
  flex: none;
}

@media(min-width:1200px) {
  .alv-lib .libnav-m {
    display: none
  }
}

/* ===================== Hero ===================== */
.alv-lib .hero {
  display: block;
  min-height: 0;
  position: relative;
  overflow: hidden;
  background: #0b1a11;
  padding: calc(38px + clamp(35px, 6.5vh, 75px)) 0 clamp(36px, 6.5vh, 75px);
  text-align: center
}

.alv-lib .hero .seal-bg {
  position: absolute;
  top: 25%;
  left: 25%;
  transform: translate(150%, -60%);
  width: min(52vw, 560px);
  opacity: 0.1;
  filter: saturate(.25);
  z-index: 0;
  pointer-events: none
}

.alv-lib .hero .wrap {
  position: relative;
  z-index: 1
}

/* The estate's kick, not a larger one. This was --fs-eyebrow-lg at .34em
   where `.alv-ed .kick` is --fs-eyebrow at .28em, so the Library's hero label
   ran a rung above every other hero label on the site. */
.alv-lib .hero .kick {
  font-family: var(--word);
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 16px
}

/* THE INDEX'S BRAND LINE IS NOT CARRIED ON A NARROW SCREEN. It reads
   "Alvará · The College of Working Equitation", which is the estate's own name
   said above the estate's own nav -- and on a phone the two are within about
   forty pixels of each other, the wordmark in the bar and the same words in
   capitals under it. On a wide screen the hero is a banner with room around it
   and the line reads as the imprint over a title page, which is what it is.

   `.page-library` and not `.alv-lib`: the hub heroes carry a `.kick` of their
   own -- the pillar's numeral and name -- which is the one thing on that page
   saying which of the three parts a reader is in, and must not go with this.
   The body class is what separates the index from the other two, and is the
   same key the footer's own rule above uses for the same reason. */
@media(max-width:900px) {
  .page-library .alv-lib .hero .kick {
    display: none
  }
}

/* The estate's hero heading, not the Library's own. It was
   clamp(52px, 8vw, 104px) at weight 500 with no letter-spacing and no case
   change — a display size and a voice this page had to itself. `--fs-display`,
   600, .08em and uppercase are what every other hero on the site is set to. */
.alv-lib .hero h1 {
  font-family: var(--word);
  font-weight: 600;
  font-size: var(--fs-display);
  line-height: 1;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--cream);
  margin: clamp(18px, 2.4vw, 30px) 0 0
}

.alv-lib .hero .h-rule {
  width: 70px;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--gold-soft), transparent);
  margin: clamp(24px, 3vw, 38px) auto
}

.alv-lib .hero .sub {
  font-family: var(--word);
  font-style: italic;
  font-size: var(--fs-prose);
  line-height: 1.5;
  color: var(--c80);
  max-width: 40ch;
  margin: 0 auto
}

/* ===================== Ivory introduction + contents ===================== */
.alv-lib .paper {
  color: var(--ground-ink);
  position: relative;
  background-color: var(--sec-ground);
  background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A//www.w3.org/2000/svg%27%20width%3D%27200%27%20height%3D%27200%27%3E%3Cfilter%20id%3D%27n%27%3E%3CfeTurbulence%20type%3D%27fractalNoise%27%20baseFrequency%3D%270.9%27%20numOctaves%3D%272%27%20stitchTiles%3D%27stitch%27/%3E%3CfeColorMatrix%20type%3D%27saturate%27%20values%3D%270%27/%3E%3C/filter%3E%3Crect%20width%3D%27100%25%27%20height%3D%27100%25%27%20filter%3D%27url%28%23n%29%27%20opacity%3D%270.5%27/%3E%3C/svg%3E"), radial-gradient(var(--sec-grain-ink) 1px, transparent 1px);
  background-size: 200px 200px, 3px 3px;
  background-blend-mode: soft-light, normal
}

.alv-lib .intro {
  padding: clamp(64px, 10vw, 132px) 0
}

.alv-lib .intro .kick {
  font-family: var(--word);
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: .3em;
  text-transform: uppercase;
  color: var(--ground-kick)
}

.alv-lib .intro h2 {
  font-family: var(--word);
  font-weight: 500;
  font-size: var(--fs-h2);
  line-height: 1.05;
  color: var(--ground-ink);
  margin: clamp(14px, 1.6vw, 20px) 0 clamp(22px, 2.6vw, 34px)
}

/* The heading and the lede ran to 20ch and 60ch inside a wrap whose content box
   is 1020px, so both stopped about a third of the page short of the right while
   sitting hard against the left gutter — a column of text down one side of an
   empty page rather than a measure. They take the wrap's own width now, which
   is what puts the right-hand gutter at the same clamp(24px,5vw,80px) as the
   left. */
.alv-lib .intro .lede {
  max-width: none
}

.alv-lib .intro .lede p {
  /* set by the estate's shared text-block rule in main.css */
}

.alv-lib .intro .lede p:last-child {
  margin-bottom: 0
}

/* A wider measure is fewer lines, and the drop cap below is about two of them
   tall. `flow-root` makes the paragraph contain its own float so the letter can
   never hang out of it and indent the paragraph beneath — the same guard the
   Residencies' §VII carries, and it keeps no measurement in step with the
   letter's size. */
/* The opening capital is `.lede-main` / `.lede-sml` from main.css — the
   estate's, unscoped, and already on the front page. The Library had grown its
   own at 3.9em against the shared 2em, which is why the two pages opened with
   visibly different capitals. Nothing is declared here; the class is put on the
   paragraph instead. */

/* contents page */
.alv-lib .contents {
  margin-top: clamp(44px, 6vw, 78px);
  border-top: 1px solid var(--ground-hair)
}

.alv-lib .contents-label {
  font-family: var(--word);
  font-size: var(--fs-eyebrow);
  letter-spacing: .3em;
  text-transform: uppercase;
  color: var(--ground-mute);
  padding-top: clamp(22px, 2.6vw, 30px);
  display: block
}

.alv-lib .contents a {
  display: flex;
  align-items: baseline;
  gap: clamp(16px, 2vw, 30px);
  padding: clamp(18px, 2.3vw, 28px) 0;
  border-bottom: 1px solid var(--ground-hair);
  transition: padding-left .35s cubic-bezier(.2, .6, .2, 1)
}

.alv-lib .contents a .cn {
  font-family: var(--word);
  font-size: calc(clamp(18px, 2vw, 24px) * var(--fs-scale));
  color: var(--gold);
  width: 2.4ch;
  flex: none;
  letter-spacing: .05em
}

.alv-lib .contents a .ct {
  font-family: var(--word);
  font-weight: 500;
  font-size: calc(clamp(20px, 2.2vw, 26px) * var(--fs-scale));
  color: var(--ground-ink);
  line-height: 1.1;
  flex: 1
}

.alv-lib .contents a .cx {
  font-family: var(--body);
  font-size: var(--fs-meta);
  color: var(--ground-mute);
  letter-spacing: .02em;
  white-space: nowrap
}

.alv-lib .contents a .cx .ar {
  display: inline-block;
  transition: transform .3s;
  color: var(--gold)
}

.alv-lib .contents a:hover {
  padding-left: 10px
}

.alv-lib .contents a:hover .cx .ar {
  transform: translateX(5px)
}

/* search */
.alv-lib .lib-search {
  margin-top: clamp(30px, 4vw, 46px);
  position: relative;
  max-width: 440px
}

.alv-lib .lib-search input {
  width: 100%;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--ground-hair);
  font-family: var(--word);
  font-size: var(--fs-prose);
  color: var(--ground-ink);
  padding: 10px 2px 12px;
  transition: border-color .3s
}

.alv-lib .lib-search input::placeholder {
  color: var(--ground-mute)
}

.alv-lib .lib-search input:focus {
  outline: none;
  border-color: var(--gold)
}

.alv-lib .lib-search .slabel {
  font-family: var(--word);
  font-size: var(--fs-eyebrow);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--ground-mute);
  display: block;
  margin-bottom: 4px
}

/* ===================== Editorial plates ===================== */
.alv-lib .plate {
  background: var(--g3);
  padding: clamp(56px, 9vw, 120px) 0;
  position: relative
}

.alv-lib .plate-fig {
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 var(--gutter)
}

.alv-lib .plate-img {
  width: 100%;
  height: auto;
  display: block;
  box-shadow: 0 30px 70px -40px rgba(0, 0, 0, .85)
}

.alv-lib .plate-cap {
  margin-top: clamp(16px, 1.8vw, 22px);
  display: flex;
  align-items: center;
  gap: 14px;
  font-family: var(--word);
  font-size: var(--fs-eyebrow);
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--c45)
}

.alv-lib .plate-num {
  font-family: var(--word);
  color: var(--gold-soft);
  letter-spacing: .1em;
  padding-right: 14px;
  border-right: 1px solid var(--gold-line)
}

/* ===================== Branch catalogue (ivory) ===================== */
.alv-lib .branch {
  padding: clamp(60px, 9vw, 128px) 0;
  scroll-margin-top: 120px
}

.alv-lib .lib-index {
  border-top: 1px solid var(--ground-hair)
}

/* `scroll-margin-top` clears the site nav, which is fixed over the top of the
   page: without it the rail's contents list lands each entry underneath it. It
   matches `.branch`'s own, so a Branch row and an entry row stop in the same
   place. */
.alv-lib .lib-entry {
  display: flex;
  gap: clamp(18px, 2.6vw, 40px);
  align-items: flex-start;
  padding: clamp(22px, 2.8vw, 34px) 0;
  border-bottom: 1px solid var(--ground-hair);
  scroll-margin-top: 120px;
  transition: padding-left .4s cubic-bezier(.2, .6, .2, 1), background-color .4s
}

.alv-lib .lib-num {
  font-family: var(--word);
  font-size: calc(clamp(15px, 1.5vw, 18px) * var(--fs-scale));
  color: var(--gold);
  letter-spacing: .08em;
  width: 2.6ch;
  flex: none;
  padding-top: .55em
}

.alv-lib .lib-body {
  flex: 1;
  display: block
}

.alv-lib .lib-corner {
  display: block;
  font-family: var(--word);
  font-size: var(--fs-eyebrow-sm);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 8px
}

.alv-lib .lib-title {
  display: block;
  font-family: var(--word);
  font-weight: 500;
  font-size: calc(clamp(20px, 2.2vw, 26px) * var(--fs-scale));
  line-height: 1.14;
  color: var(--ground-ink);
  transition: color .3s
}

.alv-lib .lib-desc {
  display: block;
  font-family: var(--body);
  font-size: calc(clamp(15px, 1.25vw, 17px) * var(--fs-scale));
  line-height: calc(1.62 * var(--lh-scale));
  color: var(--ground-ink-soft);
  margin-top: 9px;
  max-width: 66ch
}

.alv-lib .lib-more {
  display: inline-block;
  margin-top: 14px;
  font-family: var(--word);
  font-size: var(--fs-eyebrow);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--gold);
  opacity: 0;
  transform: translateY(2px);
  transition: opacity .35s, transform .35s
}

.alv-lib .lib-more .ar {
  display: inline-block;
  transition: transform .3s
}

.alv-lib .lib-entry:hover {
  padding-left: clamp(8px, 1vw, 16px);
  background-color: rgba(184, 150, 46, .045)
}

.alv-lib .lib-entry:hover .lib-title {
  color: #3a4c2b
}

.alv-lib .lib-entry:hover .lib-more {
  opacity: 1;
  transform: none
}

.alv-lib .lib-entry:hover .lib-more .ar {
  transform: translateX(5px)
}

.alv-lib .lib-entry:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px
}

.alv-lib .lib-entry.is-hidden {
  display: none
}

/* ===================== Closing ===================== */
/* The page closes on `components/_ledger.html` like every other page on the
   estate, so `.close` and its `.c-lead` / `.c-orn` / `.c-body` / `.c-actions`
   are gone -- nothing renders them.

   `.alv-lib .btn` went with them. It was the only rule still styling anything
   here, and what it styled was the shared closer's button, two pixels
   narrower and in a different ink than the same button on every other page.
   main.css carries `.btn` now. */

@media(max-width:640px) {
  .alv-lib .lib-entry {
    gap: 14px
  }

  .alv-lib .contents a {
    flex-wrap: wrap;
    gap: 8px 18px
  }

  .alv-lib .contents a .cx {
    width: 100%;
    padding-left: calc(2.4ch + 18px)
  }

  .alv-lib .lib-more {
    opacity: 1;
    transform: none
  }
}

@media(prefers-reduced-motion:reduce) {
  .alv-lib .reveal {
    opacity: 1;
    transform: none;
    transition: none
  }

  .alv-lib * {
    scroll-behavior: auto
  }
}
/* =====================================================================
   THE PILLAR HUBS

   Composition, not a new vocabulary. Everything a hub is made of already
   existed for the index — the hero, the plate, the paper ground, the intro
   drop cap, the numbered entry rows, the contents language — and this block
   only does the three things that composition needs:

     1. the parts of a hub the index has no equivalent for (a breadcrumb in a
        hero, prose sections on paper, a sibling-pillar footer);
     2. the index's own rules, reached from `.hub` where the index reaches them
        from `.branch`;
     3. nothing else. No colour, no face, no rule weight and no spacing step
        that is not already in this sheet or in the ground contract.

   The hub has no rail. The index's rail exists to move between three pillars
   and thirty entries; a hub is one pillar, its entries are the page, and the
   sibling footer carries the other two. A fixed panel would be furniture
   without a job.
   ===================================================================== */

/* --- the hero's breadcrumb ------------------------------------------------
   The trail sits above the H1, per Global Rule 5. It is centred because the
   hero is, and it is the hero's own eyebrow scale so it reads as a label
   rather than as a line of text. The separator is CSS: written into the markup
   it is announced between every level, and it would then also have to be kept
   out of the BreadcrumbList `name` values by hand. */
.alv-lib .hero .hub-crumb ol {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: baseline;
  gap: 0 .5rem;
  margin: 0 0 clamp(20px, 2.6vw, 32px);
}

.alv-lib .hero .hub-crumb {
  font-family: var(--word);
  font-size: var(--fs-eyebrow);
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--c45);
}

.alv-lib .hero .hub-crumb a {
  color: var(--gold-soft);
  text-decoration: none;
  transition: color .3s;
}

.alv-lib .hero .hub-crumb a:hover {
  color: var(--cream);
}

.alv-lib .hero .hub-crumb li + li::before {
  content: "\203A";
  margin-right: .5rem;
  color: var(--gold-line);
}

/* The hub's H1 is a question, not a two-word title — it needs a measure and a
   step down from the index's 104px display size, which was set for the word
   "The Library". */
.alv-lib .hero h1 {
  max-width: 22ch;
  margin-inline: auto;
}

/* --- the copy -------------------------------------------------------------
   The lede takes the index's intro treatment, drop cap and all. The sections
   below it are the same paper prose the index's `.intro .lede p` sets, reached
   by tag because this copy is rendered from markdown and carries no classes. */
.alv-lib .hub-copy {
  padding: clamp(56px, 8vw, 110px) 0 clamp(64px, 9vw, 120px);
}

.alv-lib .hub-lede {
  padding: 0;
  max-width: var(--measure);
  margin-inline: auto;
}

.alv-lib .hub-sections {
  margin-top: clamp(40px, 5vw, 68px);
  max-width: var(--measure);
  margin-inline: auto;
}

/* One section heading for the Library. The hub's sections carried a hairline
   rule above each one and an article's did not, so the same heading looked
   like two different things depending on which kind of page it was on. The
   sizes always agreed — both read --fs-h2 — which is what made the difference
   hard to name: it was the rule and the spacing, not the type. */
.alv-lib .hub-sections h2,
.alv-lib .lib-body h2 {
  font-family: var(--word);
  font-weight: 500;
  font-size: var(--fs-h2);
  line-height: 1.08;
  color: var(--ground-ink);
  margin: clamp(44px, 5.5vw, 74px) 0 clamp(16px, 1.8vw, 22px);
  padding-top: clamp(22px, 2.6vw, 32px);
  border-top: 1px solid var(--ground-hair);
}

.alv-lib .hub-sections h2:first-child,
.alv-lib .lib-body h2:first-child {
  margin-top: 0;
}

/* The toc extension appends a permalink to every heading. Worth keeping — the
   ids come from the Roman numerals and the registers cite sections by them —
   but shown on hover and focus rather than standing in the heading. Same
   treatment as the articles; see the note in main.css. */
.alv-lib .hub-sections h2 .toc-link,
.alv-lib .hub-sections h3 .toc-link,
.alv-lib .lib-body h2 .toc-link,
.alv-lib .lib-body h3 .toc-link {
  opacity: 0;
  margin-left: .35em;
  text-decoration: none;
  transition: opacity .2s;
}

.alv-lib .hub-sections h2:hover .toc-link,
.alv-lib .hub-sections h3:hover .toc-link,
.alv-lib .hub-sections .toc-link:focus-visible,
.alv-lib .lib-body h2:hover .toc-link,
.alv-lib .lib-body h3:hover .toc-link,
.alv-lib .lib-body .toc-link:focus-visible {
  opacity: .55;
}

.alv-lib .hub-sections h3,
.alv-lib .lib-body h3 {
  font-family: var(--word);
  font-weight: 500;
  font-size: calc(clamp(19px, 1.9vw, 24px) * var(--fs-scale));
  line-height: 1.2;
  color: var(--ground-ink);
  margin: clamp(26px, 3vw, 38px) 0 .5em;
}

.alv-lib .hub-sections p {
  /* set by the estate's shared text-block rule in main.css */
}

/* EB Garamond ships 400 and 500 here — see the <link> in base.html. A `strong`
   left to the browser asks for 700, which no loaded face answers, so the
   browser SYNTHESISES one by smearing the 500. That is the same fault as a
   Cormorant title at 400 falling back to Georgia, and it is why bold prose
   read heavy and blurred beside the text around it.

   600 is loaded for exactly this, and the emphasis is carried by colour too: body prose is `--ground-ink-soft` and this is the full ink. */
.alv-lib .hub-sections strong,
.alv-lib .lede strong,
.alv-lib .lib-desc strong {
  font-weight: 600;
  color: var(--ground-ink);
}

/* A link inside a `strong` must not compound. The link already carries a
   colour and a rule under it; adding weight on top made a bolded link read as
   a different, louder kind of link than the plain one three words earlier in
   the same sentence — which is what a run like "Working Dressage, Ease of
   Handling, Speed and Cattle" showed, half of it linked and all of it bold. */
.alv-lib .hub-sections strong a,
.alv-lib .lede strong a {
  font-weight: 600;
}

.alv-lib .hub-sections a {
  color: var(--ground-ink);
  text-decoration: none;
  border-bottom: 1px solid var(--gold-line);
  transition: border-color .3s, color .3s;
}

.alv-lib .hub-sections a:hover {
  color: #3a4c2b;
  border-bottom-color: var(--gold);
}

/* Lists, on a hub and in an article alike.
 
   `.alv-lib * { margin: 0; padding: 0 }` at the head of this sheet strips the
   browser's list indent, and only the hub had ever put one back. So 62 list
   items across 22 of the 27 clusters were rendering with their markers hard
   against the measure — the type was right, because it inherits from the
   body, which is what made it look like a spacing fault rather than a missing
   rule.
 
   The marker sits inside the content box: outside it, at this measure, a disc
   hangs into the gutter the figures break out into. */
.alv-lib .hub-sections ul,
.alv-lib .hub-sections ol,
.alv-lib .lib-body ul,
.alv-lib .lib-body ol {
  margin: 0 0 1.05em;
  padding-left: 1.4em;
  color: var(--ground-ink-soft);
  font-size: var(--fs-body);
  line-height: calc(1.45 * var(--lh-scale));
  list-style-position: outside;
}

.alv-lib .hub-sections li,
.alv-lib .lib-body li {
  margin-bottom: .35em;
  padding-left: .25em;
}

.alv-lib .hub-sections li::marker,
.alv-lib .lib-body li::marker {
  color: var(--gold);
}

/* A run of `**thing** — what it is` rows is a two-column list written as a
   one-column one. The dash is the copy's, so the layout only has to stop the
   term running into the description: the term takes the full ink and the rest
   keeps the prose colour. */
.alv-lib .hub-sections li > strong:first-child,
.alv-lib .lib-body li > strong:first-child {
  color: var(--ground-ink);
}

/* --- Read next ------------------------------------------------------------
   The further-reading pointers, ruled publishable on 21 August 2026. On paper
   rather than on the dark article ground, so it is the entry rows' gold hair
   rule and the index's eyebrow, not main.css's cream-on-green. The arrow is
   drawn here for the same reason as the breadcrumb separator above. */
.alv-lib .hub-sections .lib-readnext {
  border-left: 2px solid var(--gold-line);
  padding-left: clamp(14px, 1.6vw, 20px);
  margin: clamp(26px, 3vw, 38px) 0;
  font-size: calc(clamp(15px, 1.25vw, 17px) * var(--fs-scale));
  color: var(--ground-ink-soft);
}

.alv-lib .hub-sections .lib-readnext strong {
  display: block;
  font-family: var(--word);
  font-weight: 600;
  font-size: var(--fs-eyebrow);
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--ground-kick);
  margin-bottom: .35em;
}

.alv-lib .hub-sections .lib-readnext strong::after {
  content: "\2192";
  margin-left: .5em;
  color: var(--gold);
}

.alv-lib .hub-sections .lib-readnext a {
  color: var(--ground-ink);
}

/* --- the pillar's entries -------------------------------------------------
   The index's own rows. Only the section wrapper is new: the rows, their
   numbers, titles, descriptions and hover behaviour are `.lib-entry` as the
   index sets it. */
.alv-lib .hub-index-sec {
  padding: clamp(56px, 8vw, 110px) 0 clamp(64px, 9vw, 124px);
  border-top: 1px solid var(--ground-hair);
}

/* --- the other pillars ----------------------------------------------------
   The index's contents rows, on the dark ground so the page closes the way it
   opened. */
.alv-lib .hub-siblings {
  background: var(--g3);
  padding: clamp(56px, 8vw, 104px) 0 clamp(64px, 9vw, 116px);
}

.alv-lib .hub-siblings .contents-label {
  color: var(--c45);
  padding-top: 0;
  margin-bottom: clamp(18px, 2.2vw, 28px);
}

.alv-lib .hub-sib-list {
  border-top: 1px solid var(--gold-line);
}

.alv-lib .hub-sib-list a {
  display: grid;
  grid-template-columns: 2.4ch 1fr;
  align-items: baseline;
  column-gap: clamp(16px, 2vw, 30px);
  row-gap: 6px;
  padding: clamp(20px, 2.5vw, 30px) 0;
  border-bottom: 1px solid var(--gold-line);
  text-decoration: none;
  transition: padding-left .35s cubic-bezier(.2, .6, .2, 1);
}

.alv-lib .hub-sib-list a:hover {
  padding-left: 10px;
}

.alv-lib .hub-sib-list .cn {
  font-family: var(--word);
  font-size: calc(clamp(18px, 2vw, 24px) * var(--fs-scale));
  color: var(--gold);
  letter-spacing: .05em;
}

.alv-lib .hub-sib-list .ct {
  font-family: var(--word);
  font-weight: 500;
  font-size: calc(clamp(20px, 2.2vw, 26px) * var(--fs-scale));
  line-height: 1.1;
  color: var(--cream);
  grid-column: 2;
}

.alv-lib .hub-sib-list .cx {
  grid-column: 2;
  font-family: var(--body);
  font-size: var(--fs-meta);
  line-height: 1.6;
  color: var(--c45);
  max-width: 60ch;
}

.alv-lib .hub-sib-list .cx .ar {
  display: inline-block;
  color: var(--gold);
  transition: transform .3s;
}

.alv-lib .hub-sib-list a:hover .cx .ar {
  transform: translateX(5px);
}

.alv-lib .hub-sib-list .hub-sib-all .ct,
.alv-lib .hub-sib-list .hub-sib-all .cx {
  grid-column: 1 / -1;
}

@media (max-width: 720px) {
  .alv-lib .hub-sib-list a {
    grid-template-columns: 2ch 1fr;
  }
}

/* =====================================================================
   THE STUDY RAIL — a page's figures and photographs, gathered

   The reader's `.alr-study` pattern, in the Library's own palette. Same
   mechanics, because they are what make it work rather than what makes it look
   right:

   - the stage is a fixed box and the embed inside it is 400% × 400% scaled to
     0.25 from its top-left corner. The figures are whole HTML documents whose
     type and rules are drawn to a width; sizing one down instead would let it
     reflow into a 280px column and give a thumbnail that looks nothing like
     the figure it stands for.
   - `pointer-events: none` on the frame, so the click reaches the link and
     never the document inside it.

   Where the reader's rail is a panel in a fixed shell, this one is sticky
   inside a scrolling page and folds under the copy on narrow screens. Below
   1200px it is not fixed furniture at all — the page is one column there and
   the rail belongs after the reading, not beside it.
   ===================================================================== */

.alv-lib .lib-study-h {
  font-family: var(--word);
  font-size: var(--fs-eyebrow);
  letter-spacing: .24em;
  text-transform: uppercase;
  color: var(--c45);
  padding-bottom: 12px;
  margin-bottom: 16px;
  border-bottom: 1px solid var(--gold-line);
}

.alv-lib .lib-fig-th {
  display: block;
  width: 100%;
  margin-bottom: 18px;
  padding: 0;
  text-align: left;
  border: 0;
  background: transparent;
  cursor: pointer;
  font: inherit;
  color: inherit;
}

.alv-lib .lib-fth-stage {
  position: relative;
  display: block;
  overflow: hidden;
  aspect-ratio: 4 / 3;
  background: var(--sec-ground);
  border: 1px solid var(--gold-line);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .25);
  transition: border-color .2s, box-shadow .2s;
}

.alv-lib .lib-fig-th:hover .lib-fth-stage {
  border-color: var(--gold);
  box-shadow: 0 6px 18px -8px rgba(0, 0, 0, .7);
}

.alv-lib .lib-fig-th:focus-visible .lib-fth-stage {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}

/* 400% at quarter scale — the figure at its own drawn width, shown small. */
.alv-lib .lib-fth-frame {
  position: absolute;
  top: 0;
  left: 0;
  width: 400%;
  height: 400%;
  border: 0;
  transform: scale(.25);
  transform-origin: top left;
  pointer-events: none;
}

.alv-lib .lib-fth-stage img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* A plate needs none of the frame's 400%-at-quarter trick: an SVG scales
   natively, so it is simply drawn at the panel's width.

   AND IT SETS ITS OWN HEIGHT. Every other thumbnail is given a 4:3 stage
   because an iframe has no natural height and a photograph would otherwise
   jump the layout as it loads. A plate has neither problem and is not 4:3 —
   held to that box it letterboxes, which is a thumbnail of the figure with a
   band of nothing under it. `aspect-ratio: auto` hands the height back to the
   drawing, which is the one thing on the page that knows it. */
.alv-lib .lib-fig-th--plate .lib-fth-stage {
  aspect-ratio: auto;
  background: transparent;
}

.alv-lib .lib-fig-th--plate .lib-fth-stage svg {
  display: block;
  width: 100%;
  height: auto;
  pointer-events: none;
}

/* THE STUDY RAIL IS A RAIL OR IT IS NOTHING.

   Below 1200px there is no second column to put it in, and it was becoming a
   band of thumbnails instead. The panel sits BEFORE the article in the markup,
   because above 1200px it is `position: fixed` and the order is the reading's
   to decide — so as a static band it landed above the breadcrumb and the H1,
   and a page opened on four pictures with its own title underneath them. (The
   comment that used to stand here said the band sat after the reading. It did
   not, and had not for some time.)

   Nothing is lost by dropping it. Every figure it gathers is in the prose a
   screen or two below, each where the passage that explains it puts them; the
   panel is a convenience for a reader who has a spare column, and on a phone
   there is no spare column and a good deal more scrolling to do. `display:
   none` rather than a visual hide, since the alternative is a screen reader
   announcing every figure on the page twice. */
.alv-lib .lib-study {
  display: none;
}

@media (min-width: 1200px) {
  /* Beside the reading, and the page clears it the way it clears the contents
     rail on the other side.

     `.reads` is every hub and every article, whether or not that page carries a
     figure — not `.has-study`, which was only the ones that do. With the
     reserve conditional, an article with figures read in an 869px column and
     the article linked from it read in a 1169px one, so the text moved across
     the screen as a reader went through the Library. The index keeps the full
     width: its plates and entry rows are a full-bleed design, not a measure. */
  .alv-lib .page.reads {
    margin-right: 300px;
  }

  .alv-lib .page.reads .lib-study {
    display: block;
    position: fixed;
    top: 76px;
    right: 0;
    bottom: 0;
    width: 300px;
    margin: 0;
    padding: 24px 20px 40px;
    overflow-y: auto;
    background: #0b1d13;
    border-top: 0;
    border-left: 1px solid var(--gold-line);
    z-index: 60;
  }
}

/* --- where the reader is, in the contents rail ---------------------------- */
.alv-lib .libnav-sub a.is-here {
  color: var(--cream);
}

.alv-lib .libnav-sub a.is-here .sn {
  color: var(--gold);
}

.alv-lib .libnav-sub a.is-here .st {
  border-bottom: 1px solid var(--gold-soft);
}

/* The pillar row is both things: the name goes to the hub, the rest of the
   summary still toggles the entries. */
.alv-lib .libnav-branch summary .rl {
  color: inherit;
  text-decoration: none;
}

.alv-lib .libnav-branch summary .rl:hover {
  color: var(--cream);
  text-decoration: underline;
  text-decoration-color: var(--gold-soft);
}

.alv-lib .libnav-branch summary .rl.is-here {
  color: var(--cream);
}

.alv-lib .libnav-branch summary .rl:focus-visible {
  outline: 2px solid var(--gold-soft);
  outline-offset: 2px;
}

/* =====================================================================
   THE SHARED EDITORIAL VOCABULARY

   `.kick` and `.head` as `.alv-ed` declares them, reading the same tokens and
   the same ground contract. Declared here rather than by loading
   alvara-editorial.css: that sheet is 46 kB of page furniture the Library does
   not use, and its hero, rail and paper spreads would collide with this one's.
   What the Library needs from it is the type contract, and this is that.

   If the editorial values move, these move with them — they are the same
   tokens, not copies of the numbers.
   ===================================================================== */

.alv-lib h1,
.alv-lib h2,
.alv-lib h3,
.alv-lib h4 {
  font-family: var(--word);
  font-weight: 500;
  line-height: 1.16;
  color: var(--ground-ink);
}

/* An article's title, which is not a hero.
   `--fs-display` is uppercase, open-tracked and 600 — right over the one or
   two words a hero carries, wrong over "Working Equitation Dress and Turnout",
   where it reads as a banner rather than a title. So an h1 outside `.hero`
   takes the ordinary heading voice: mixed case, 500, no tracking, a step above
   `--fs-h2` and no more. The `.hero h1` rule below still overrides this on the
   index and the pillar hubs. */
.alv-lib h1 {
  font-size: calc(clamp(28px, 3vw, 36px) * var(--fs-scale));
  margin: 0 0 1.5rem;
}

.alv-lib h2 {
  font-size: var(--fs-h2);
  line-height: 1.08;
}

/* Cormorant Garamond ships 500 and 600 only. A title left at 400 falls back to
   Georgia, which is the bug the editorial sheet's v3 revision was written to
   fix; pinning it here keeps the Library out of the same hole. */
.alv-lib .head h2,
.alv-lib .head h1 {
  font-family: var(--word);
  font-weight: 500;
  font-style: normal;
  margin: 6px 0 0;
  max-width: none;
}

/* A head's own heading takes no section rule above it: the block already
   separates itself, and the hairline belongs between sections. */
.alv-lib .head h2 {
  padding-top: 0;
  border-top: 0;
}

.alv-lib .kick {
  display: inline-block;
  font-family: var(--word);
  font-size: var(--fs-eyebrow);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--ground-kick);
  font-weight: 600;
}

.alv-lib .head .kick {
  display: block;
  font-size: var(--fs-label);
  letter-spacing: .24em;
  font-weight: 600;
}

/* A head standing straight over its own list rather than over a section. */
.alv-lib .head.tight {
  margin-bottom: clamp(22px, 2.8vw, 34px);
}

.alv-lib .head .deck {
  font-family: var(--word);
  font-style: italic;
  font-size: var(--fs-prose);
  line-height: 1.5;
  color: var(--ground-ink-soft);
  margin-top: clamp(12px, 1.4vw, 18px);
  max-width: 52ch;
}


/* =====================================================================
   A FIGURE, OPENED

   The reader's lightbox, in the Library's palette. Same mechanics, because
   they are what make it work:

   - the panel is inside `x-if`, so the frame is created on open and destroyed
     on close. `x-show` alone would leave an animated document running behind
     a hidden overlay for the rest of the session.
   - the aspect ratio is the register's measured value, carried on the
     thumbnail. Never a fixed pixel height, never resized by script — the
     figures are drawn to a width and told us what shape they are.
   ===================================================================== */

/* Block layout, not flex, and this is the whole reason:

   A centred flex child taller than its scroll container has an UNREACHABLE
   top. `margin: auto` distributes the overflow to both sides, and `scrollTop`
   cannot go negative, so whatever spills above the fold can never be scrolled
   to. The panel was 1067px in a 900px window and its first 80px were simply
   gone. Block layout with a horizontal auto margin starts the panel at the top
   of the scroll area, so every part of it is reachable.

   A short figure therefore sits at the top rather than centred. That is the
   trade, and it is the right way round: predictable beats pretty when the
   alternative loses part of the thing being shown. */
.alv-lib .lib-lightbox {
  position: fixed;
  inset: 0;
  /* Above `.alv-nav`, which is fixed at z-index 100 across the top 85px of
     every page. At 90 — the reader's value, where there is no such bar — the
     nav painted over the head of the dialog and took the close button with it.
     Below the cookie banner at 10000, which has to stay reachable. */
  z-index: 200;
  display: block;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: clamp(12px, 2.5vh, 28px);
  background: rgba(11, 26, 17, .84);
}

.alv-lib .lib-lb-panel {
  position: relative;
  display: flex;
  flex-direction: column;
  width: min(1100px, 100%);
  margin: 0 auto;
  padding: 16px;
  background: var(--sec-ground, #ece4d1);
  border: 1px solid var(--gold-line);
  box-shadow: 0 30px 70px rgba(0, 0, 0, .5);
}

/* Sticky in the panel's own corner, not fixed to the window's.

   Absolute in the panel scrolled it off the screen with the panel. Fixed to
   the viewport kept it visible but stranded it a hundred pixels clear of the
   figure it closes, because the panel is 1100px in a wider window. Sticky is
   both — it belongs to the panel and it never leaves the top of the window.

   `align-self` puts it at the panel's right edge and the negative margin takes
   its row back out of the flex column, so it sits over the figure's corner
   rather than pushing the drawing down by its own height. */
.alv-lib .lib-lb-x {
  position: sticky;
  top: 0;
  align-self: flex-end;
  margin-bottom: -34px;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  font-family: var(--body);
  font-size: 21px;
  line-height: 1;
  color: var(--g3, #0f2417);
  background: rgba(242, 237, 224, .92);
  border: 0;
  border-radius: 100px;
  box-shadow: 0 1px 4px rgba(11, 26, 17, .28);
  cursor: pointer;
  transition: background .15s, color .15s;
}

.alv-lib .lib-lb-x:hover,
.alv-lib .lib-lb-x:focus-visible {
  background: var(--gold);
  color: var(--g3, #0f2417);
  outline: none;
}

.alv-lib .lib-lb-stage {
  flex: none;
}

.alv-lib .lib-lb-frame {
  display: block;
  width: 100%;
  border: 0;
  /* The shape it holds until it reports its real height. A figure that never
     reports keeps it. */
  aspect-ratio: 4 / 3;
}

.alv-lib .lib-lb-stage img {
  display: block;
  max-width: 100%;
  margin: 0 auto;
}

.alv-lib .lib-lb-foot {
  flex: none;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--gold-line);
}

.alv-lib .lib-lb-cap {
  margin: 0;
  font-family: var(--body);
  font-size: var(--fs-note);
  line-height: 1.4;
  color: #31432f;
}

.alv-lib .lib-lb-note {
  flex: none;
  font-family: var(--word);
  font-size: var(--fs-micro);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: #6f6a52;
  white-space: nowrap;
}

/* =====================================================================
   TABLES IN THE COPY

   Eleven of the thirty pages carry one, and nothing styled them: they were
   rendering as the browser's default — no rules, no padding, columns jammed
   together, and the next paragraph hard against the last row.

   The border is the gold hairline the rest of the Library divides with, so a
   table reads as part of the page rather than as pasted-in data. The head rule
   is the solid gold, because the header row is the one line that has to be
   findable when a reader comes back to a figure-dense page mid-sentence.

   Both grounds are covered by the contract: the article and the hub's copy sit
   on paper, and the tokens resolve to the ivory values there.
   ===================================================================== */

.alv-lib .lib-body table,
.alv-lib .hub-sections table {
  width: 100%;
  border-collapse: collapse;
  /* The prose rhythm, plus the 10px the following copy was missing. */
  margin: 0 0 calc(1.05em + 10px);
  font-family: var(--body);
  font-size: var(--fs-note);
  line-height: calc(1.5 * var(--lh-scale));
  color: var(--ground-ink-soft);
  border: 1px solid var(--gold-line);
}

/* A wide regulatory table must not push the measure open on a phone. */
.alv-lib .lib-body table,
.alv-lib .hub-sections table {
  display: block;
  overflow-x: auto;
}

.alv-lib .lib-body th,
.alv-lib .hub-sections th {
  font-family: var(--word);
  font-weight: 600;
  font-size: var(--fs-label);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ground-ink);
  text-align: left;
  vertical-align: bottom;
  padding: 10px 14px;
  border-bottom: 2px solid var(--gold);
}

.alv-lib .lib-body td,
.alv-lib .hub-sections td {
  padding: 10px 14px;
  vertical-align: top;
  border-top: 1px solid var(--gold-line);
}

.alv-lib .lib-body tbody tr:first-child td,
.alv-lib .hub-sections tbody tr:first-child td {
  border-top: 0;
}

/* The first column is the row's name in every one of these tables — the
   obstacle, the level, the clause — so it carries the ink the row is read by.

   IT DOES NOT CARRY `white-space: nowrap`, AND THAT WAS A CLAIM ABOUT ENGLISH.
   A name is short and does not need holding on one line; what `nowrap` did was
   forbid a wrap the cell might genuinely need, and the Cattle Trial's penalty
   table names its faults in a sentence — "Une vache autre que celle en cours de
   tri franchit la ligne de confinement". Held unbroken that is wider than the
   measure, so the table grew a scrollbar at a desktop width in four languages
   while English, whose fault names are shorter, fitted. The wrapping below 820px
   is the design and stays; this was the same table scrolling on a large screen. */
.alv-lib .lib-body td:first-child,
.alv-lib .hub-sections td:first-child {
  color: var(--ground-ink);
}

.alv-lib .lib-body table strong,
.alv-lib .hub-sections table strong {
  font-weight: 600;
  color: var(--ground-ink);
}

/* =====================================================================
   A FIGURE IN THE COPY

   Global Rule 10. An <iframe>, not an inline component: every asset declares
   `*{margin:0;padding:0;box-sizing:border-box}` and styles `body`, several use
   global function names, and one page embeds four of them. The iframe boundary
   is the isolation they were built assuming.

   The height comes from `aspect-ratio` on the element, set from the register's
   measured value — never a fixed pixel height, and never resized by script.
   Those measurements were taken in the Georgia fallback and are an upper
   bound; they are due a re-measure once the real EB Garamond faces ship.

   THE RULE THAT OUTRANKS THE OTHERS: the interactive is never the only place
   essential information exists. The article is canonical and the figure is
   evidence — which is also why a figure sits at the END of the section it
   belongs to, after the claim it supports.
   ===================================================================== */

.alv-lib .lib-figure--interactive {
  margin: clamp(28px, 3.4vw, 44px) 0;
}

.alv-lib .lib-figure--interactive iframe {
  display: block;
  width: 100%;
  border: 0;
  background: var(--g3);
}

.alv-lib .lib-figure--interactive figcaption {
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid var(--gold-line);
  font-family: var(--body);
  font-size: var(--fs-note);
  line-height: 1.5;
  color: var(--ground-ink-soft);
}

.alv-lib .lib-figure--interactive figcaption strong {
  font-family: var(--word);
  font-weight: 600;
  letter-spacing: .06em;
  color: var(--ground-kick);
}

/* A figure is wider than the measure it interrupts: these are drawn to a width
   and a 74ch column squeezes them.

   The break-out is a fixed 2.5rem each side rather than a `ch` value or
   `100cqw`. `ch` is measured on the figure's own font and drifts with the type
   scale; `100cqw` needs a `container-type` nobody declared, so it resolved
   against the viewport and put the figure 8px into the rails on both sides.
   2.5rem is inside the 51px the column has spare at every width the rails
   appear at. */
@media (min-width: 900px) {
  .alv-lib .lib-figure--interactive {
    width: calc(100% + 5rem);
    margin-left: -2.5rem;
    margin-right: -2.5rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .alv-lib .lib-figure--interactive iframe {
    /* The assets carry their own guards; this is the page saying so too. */
    scroll-behavior: auto;
  }
}

/* =====================================================================
   THE COLLEGE PLATES

   Sixteen of the thirty pages close on a College section carrying one of
   these. They are not interactives and not photographs: each is a single
   delivered SVG, inlined into the page DOM by `place_plates()`, drawn in live
   text that asks for the estate's own EB Garamond and Cormorant Garamond.
   Inlined is the whole point — an SVG behind `<img src>` renders in restricted
   mode and reaches neither the page's stylesheet nor its webfonts.

   THEY STAND MID-SECTION, AND THAT IS DELIBERATE. The rule stated above, that
   a figure sits at the END of the section it belongs to after the claim it
   supports, is the right rule for an interactive, which is evidence for a
   claim the prose has already made. Every one of these is the other way round:
   the plate reveals something and the prose then works through it, so placing
   it at the foot spends the figure before it appears. The College's build
   blocks call the placement load-bearing on 2.3, 2.6 and 3.1 by name. The
   anchor in the copy is where it goes.

   AND THEY DO NOT BREAK THE MEASURE. An interactive breaks out because it was
   drawn to a width; a plate is capped at 900px and centred, on the ruling that
   it must read as a figure inside the article and never as a promotional band.
   At the 74ch measure that is narrower than the column, so the cap is what
   bites and the break-out would be the wrong move twice over.

   THERE IS NO MOBILE CASE, AND THAT IS THE POINT. A plate scales with the
   column like every other figure on the page. It carried a 640px floor, a
   scroll container, a fade at the cut edge and a control opening it full
   screen — all of it built on the arithmetic that a 1200-unit drawing with
   21-unit labels puts its type at 5.6px in a 320px column. The arithmetic is
   right and the conclusion was wrong: a reader on a phone zooms, and a plate
   is the best thing on the page to zoom, being the one figure that is vector
   the whole way down and re-rasterises crisp at any magnification where the
   photographs beside it go soft. The interactives carry no such apparatus and
   never needed one. Neither does this.
   ===================================================================== */

/* THE SITE NAV IS FIXED OVER THE TOP OF THE PAGE, AND AN ANCHOR DOES NOT KNOW
   THAT. A plate is the one row of the study rail that navigates rather than
   opening a dialog — it already stands at its full width in the prose, so the
   control goes to it — and the browser lands its top at the top of the
   viewport, which puts the drawing's own title behind 85px of menu. On a plate
   shorter than the screen that reads as the figure having been CENTRED with
   its heading cut off, which is how it was reported.

   120px is `.branch`'s and `.lib-entry`'s, so a plate, a Branch row and a
   contents entry all stop in the same place. */
.alv-lib .lib-figure--plate {
  margin: clamp(28px, 3.4vw, 44px) auto;
  max-width: 900px;
  scroll-margin-top: 120px;
}

/* The delivered files carry `width="1200" height="1337"` beside the viewBox,
   and are shipped as delivered — so the attributes stay and the sheet is what
   overrides them. Without `height: auto` the plate stands at its own 1337px
   whatever width it is given. */
.alv-lib .lib-figure--plate svg {
  display: block;
  width: 100%;
  height: auto;
}

/* =====================================================================
   THE FOOTER, OVER THE RAILS

   `.alv-foot` is the estate's and is the same on every page. On a Library
   page it was running UNDER the contents rail: the rail is `position: fixed`
   at z-index 70 down the full height of the viewport, so it covered the
   footer's first 256px and the footer looked tucked behind it.

   The footer is not inside `.alv-lib`, so this is keyed on the body class
   rather than the wrapper. `position: relative` is what gives z-index
   something to act on — it is static by default, and a z-index on a static
   element does nothing at all.

   Above both rails and below the dialog: a figure opened over the page should
   still cover the footer.
   ===================================================================== */
.page-library .alv-foot,
.page-library-article .alv-foot,
.page-library-hub .alv-foot {
  position: relative;
  z-index: 80;
  background: var(--green-deep, #132D1E);
}

/* =====================================================================
   PHOTOGRAPHS IN THE COPY

   Two kinds, and they differ in where they stand rather than in how they look.

   `.lib-figure--lead` is the page's opening photograph — the register's
   "Primary editorial" on a cluster, its "Hero" on a hub — and it sits above
   the prose. `.lib-figure--photo` is one the register placed in a named
   section: on the traditions page the four countries each have their own, and
   the section headings are what the register's "France editorial" matches.

   Both break the measure like an interactive figure does, and for the same
   reason: a photograph set to 74ch of text is a postage stamp.
   ===================================================================== */

.alv-lib .lib-figure--lead,
.alv-lib .lib-figure--photo {
  margin: clamp(28px, 3.4vw, 44px) 0;
}

.alv-lib .lib-figure--lead {
  margin-top: 0;
}

.alv-lib .lib-figure--lead img,
.alv-lib .lib-figure--photo img {
  display: block;
  width: 100%;
  height: auto;
  box-shadow: 0 20px 50px -30px rgba(0, 0, 0, .8);
}

.alv-lib .lib-figure--lead figcaption,
.alv-lib .lib-figure--photo figcaption {
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid var(--gold-line);
  font-family: var(--body);
  font-style: italic;
  font-size: var(--fs-note);
  line-height: 1.5;
  color: var(--ground-ink-soft);
}

@media (min-width: 900px) {
  .alv-lib .lib-figure--lead,
  .alv-lib .lib-figure--photo {
    width: calc(100% + 5rem);
    margin-left: -2.5rem;
    margin-right: -2.5rem;
  }
}

/* =====================================================================
   A HUB'S HERO, ON PAPER

   `.paper` gives it the ivory ground, the grain and the light ground
   contract. What it cannot do on its own is undo the colours the shared hero
   rule writes for a dark one — `--cream` on the heading, `--gold` on the kick,
   `--c80` on the deck — which on ivory is cream type on an ivory sheet.

   Only `.page.hub`. The index's hero stays dark: it opens the Library and the
   plates and paper spreads follow it, where a hub is one continuous read from
   its title to its contents.
   ===================================================================== */

.alv-lib .page.hub .hero h1 {
  color: var(--ground-ink);
}

.alv-lib .page.hub .hero .kick {
  color: var(--ground-kick);
}

.alv-lib .page.hub .hero .sub {
  color: var(--ground-ink-soft);
}

.alv-lib .page.hub .hero .hub-crumb {
  color: var(--ground-mute);
}

.alv-lib .page.hub .hero .hub-crumb a {
  color: var(--ground-kick);
}

.alv-lib .page.hub .hero .hub-crumb a:hover {
  color: var(--ground-ink);
}

/* The seal watermark was drawn to sit at a tenth of its weight on a near-black
   ground. At the same opacity on ivory it is a grey smudge rather than a
   watermark, so it takes the paper's own grain weight instead. */
.alv-lib .page.hub .hero .seal-bg {
  opacity: .05;
  filter: saturate(.2) contrast(.8);
}

/* The copy below opens straight out of the hero now that both are the same
   ground — the seam between two grounds was doing the separating. */
.alv-lib .page.hub .hub-copy {
  padding-top: 0;
}

/* The hub's plate takes the ground too, so a hub is one continuous sheet from
   its title to its contents. Beige hero, dark plate, beige copy left a band
   across the middle of every hub that belonged to a page built out of
   alternating spreads — which the index is and a hub is not.

   The caption's own colours were written for the dark band. */
/* The background is set here rather than left to `.paper` on the element,
   because `.alv-lib .plate` is declared AFTER `.alv-lib .paper` in this sheet
   and the two have equal specificity — so the plate's own dark ground wins the
   tie and `.paper` never lands. The hero works by the class alone only because
   `.alv-lib .hero` happens to come earlier.

   Which is the argument for saying it outright at a specificity that does not
   depend on where in the file anything sits. `transparent` was the first
   attempt and was worse: it let the wrapper's dark ground through, so the band
   was still there in a slightly different colour. */
.alv-lib .page.hub .plate {
  padding-top: 0;
  background-color: var(--sec-ground);
  background-image:
    url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A//www.w3.org/2000/svg%27%20width%3D%27200%27%20height%3D%27200%27%3E%3Cfilter%20id%3D%27n%27%3E%3CfeTurbulence%20type%3D%27fractalNoise%27%20baseFrequency%3D%270.9%27%20numOctaves%3D%272%27%20stitchTiles%3D%27stitch%27/%3E%3CfeColorMatrix%20type%3D%27saturate%27%20values%3D%270%27/%3E%3C/filter%3E%3Crect%20width%3D%27100%25%27%20height%3D%27100%25%27%20filter%3D%27url%28%23n%29%27%20opacity%3D%270.5%27/%3E%3C/svg%3E"),
    radial-gradient(var(--sec-grain-ink) 1px, transparent 1px);
  background-size: 200px 200px, 3px 3px;
  background-blend-mode: soft-light, normal;
}

.alv-lib .page.hub .plate-cap {
  color: var(--ground-mute);
}

.alv-lib .page.hub .plate-num {
  color: var(--ground-kick);
  border-right-color: var(--gold-line);
}

.alv-lib .page.hub .plate-img {
  box-shadow: 0 20px 50px -30px rgba(0, 0, 0, .55);
}
