@charset "UTF-8";
/* The rule above is not decoration: this file contains literal
   characters in content: properties (the breadcrumb "›"), and a
   stylesheet served without a charset is decoded as Latin-1, which
   turned that separator into mojibake on the live page. */
/* thevyasa.in — corpus pages.
 *
 * These are static HTML files, so the Astra theme never runs here. To keep the
 * corpus from feeling like a different website, the palette, typeface and
 * heading treatment below are taken from thevyasa.in itself:
 *
 *   background  #FFFAF0   ink      #334155   (slate)
 *   headings    #FC9C0D   links    #3964EC
 *   typeface    Noto Serif Devanagari, the same face the theme loads
 *
 * The reading column is deliberately narrower than the theme's 1240px shell:
 * 1240px of Devanagari is far past a comfortable measure, and these pages are
 * for reading a thousand pages of scripture, not for a marketing layout.
 */

/* The regions between the start and end markers below are lifted, scoped and
   shipped as the WordPress shortcode's stylesheet — see src/embed.py. Keep the
   shelf's rules inside them, or the homepage silently loses them. */
/* @embed:start */
:root {
  --paper:      #fffaf0;
  --paper-warm: #fff0d1;
  --paper-card: #fffdf8;
  --ink:        #334155;
  --ink-soft:   #6b7a8f;
  --rule:       #ecdfc7;
  --accent:     #fc9c0d;
  --link:       #3964ec;
  --link-visit: #6b46c1;
  --mark:       #ffe9a8;
  /* Verse sits in a warm cream bubble a shade deeper than the page — the same
     cream family as the theme's header, so it reads as part of the site. */
  --verse-bg:   #fdf1da;
  --verse-edge: #f2e2c2;
  --verse-ink:  #2c2418;
  /* Mat behind a page scan, and the back-to-top control (matched to the
     WordPress side of the site). */
  --scan-mat:   #f3ece0;
  /* A search hit on the page the reader landed on. Green, and deliberately
     not the amber of an ordinary mark. */
  --hit-bg:     #baf0a2;
  --hit-ink:    #14310c;
  --hit-ring:   #74c95a;
  --totop-bg:   #f7df8f;
  --totop-ink:  #334155;
  --totop-ring: #62ea23;
  --shell:      75rem;
  --measure:    38rem;
  --serif: "Noto Serif Devanagari", "Noto Serif", "Kohinoor Devanagari",
           "Nirmala UI", Georgia, serif;

  /* ---- materials -------------------------------------------------------
     Three of them, and they never mix. WOOD is furniture: the rail across
     the top, the shelf the books stand on, the plinth at the foot. PAPER is
     content: every surface that carries text is a leaf lying on the desk.
     BRASS is hardware: the hairline where wood meets paper.

     All of it is drawn — CSS gradients over two inline SVG noise tiles — so
     the whole library costs no extra HTTP requests and nothing at all from
     the image budget: about 4KB more stylesheet over the wire, once, cached
     for a week. That matters here. The page budget is ~100KB and it is spent
     on page scans, which is what a reader actually came for.

     The oak is deliberately kept in the theme's cream family rather than
     going walnut-dark. A reader crossing from the WordPress side should feel
     they have walked into the library room of the same house, not onto a
     different website. */
  --room:       #ebdfc7;   /* the ground behind the paper: desk, not page */
  --wood-lit:   #f2e0bc;   /* light oak, the rail across the top */
  --wood-face:  #e0c79b;
  --wood-edge:  #c2a069;
  --wood-dark:  #9c7a49;
  --board-back: #513c26;   /* the panel the books stand against */
  /* The board, read from the back forward: a foreshortened top face, the lit
     arris along its front, the edge turning away from the light, and the dark
     reveal underneath. */
  --board-top:    #7f5a2e;
  --board-arris:  #c0955c;
  --board-lit:    #96703f;
  --board-shade:  #6d4c28;
  --board-reveal: #1c1207;
  --brass:      #b8901f;
  --brass-lit:  #f2dc9a;
  --cast:       rgba(58, 38, 12, 0.34);   /* what wood and paper cast */

  /* The two textures. feTurbulence rather than repeating gradients: a
     hatching reads as a hatching, whereas fractal noise reads as fibre and
     grain, which is the whole point of the exercise. stitchTiles keeps the
     tile seamless when CSS repeats it. Both are drawn at full strength and
     dialled down at the point of use, so one tile serves every surface. */
  --tex-fibre: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='f'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23f)'/%3E%3C/svg%3E");
  --tex-wood: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='600' height='300'%3E%3Cfilter id='w'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.004 .45' numOctaves='5' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='600' height='300' filter='url(%23w)'/%3E%3C/svg%3E");
}

/* Light is the default, deliberately — it matches the rest of the site, and a
   cream page is what these books look like. Dark is available but only when the
   reader asks for it; following prefers-color-scheme meant a reader arriving
   from the light WordPress side landed on a dark granth page unprompted. */
:root[data-theme="dark"] {
--paper: #15120e; --paper-warm: #221b13; --paper-card: #1c1811;
  --ink: #e7ddca; --ink-soft: #a1927c; --rule: #38301f;
  --accent: #f2ab45; --link: #9db6f0; --link-visit: #c0a6e6; --mark: #6b5410;
--verse-bg: #241d13; --verse-edge: #473b26; --verse-ink: #f6efe0;
  --scan-mat: #221b12; --totop-bg: #f7df8f; --totop-ink: #2b2318;
  --totop-ring: #62ea23;
  /* The same furniture after dark: the oak becomes rosewood and the room an
     unlit one. Paper stays the lightest thing on the page, which is what
     keeps the reading column the thing the eye goes to. */
  --room: #100d09; --wood-lit: #4a3421; --wood-face: #3b2917;
  --wood-edge: #281a0e; --wood-dark: #17100a; --board-back: #2a1d11;
  --board-top: #382613; --board-arris: #6e5029; --board-lit: #4e381d;
  --board-shade: #2c1e0f; --board-reveal: #080603;
  --brass: #8a6a17; --brass-lit: #c9a94e;
  --cast: rgba(0, 0, 0, 0.6);
  --hit-bg: #2c5f1d; --hit-ink: #e9ffdd; --hit-ring: #4f9b39;
}
/* @embed:end */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

/* The room. html carries the flat colour so a page shorter than the viewport
   still fills it; body carries the fibre, which needs a box the height of the
   content to tile across. */
html { background-color: var(--room); }

body {
  margin: 0;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background-color: var(--room);
  background-image: var(--tex-fibre);
  background-size: 200px 200px;
  background-blend-mode: soft-light;
  color: var(--ink);
  font-family: var(--serif);
  font-size: 1.0625rem;
  line-height: 1.85;
  text-rendering: optimizeLegibility;
}

a { color: var(--link); text-decoration-thickness: 1px; text-underline-offset: 0.18em; }
a:visited { color: var(--link-visit); }
a:hover { text-decoration-thickness: 2px; }

.wrap { max-width: var(--measure); margin: 0 auto; padding: 0 1.15rem; }
.wrap-wide { max-width: var(--shell); margin: 0 auto; padding: 0 1.15rem; }

/* ---- the leaf ----------------------------------------------------------
   Every surface that carries text is a sheet of paper lying on the desk: its
   own warm white, a fibre grain, a hairline of an edge and the shadow it
   casts on the room. Scoped to main.wrap, never bare .wrap, because the shelf
   page uses .wrap for inner columns that are meant to sit on the ground.

   On a phone the leaf is full bleed — 375px of screen is all measure and no
   room to spare — and the desk only shows above and below it. The margins
   appear at 46rem, where there is width to give away. */
main.wrap, .leaf {
  position: relative;
  isolation: isolate;
  /* Definite, not shrink-to-fit. main is a flex item of body now, and a flex
     item whose cross-axis margins are auto (which `.wrap`'s `margin: 0 auto`
     makes them) opts out of stretch and is sized shrink-to-fit instead —
     floored at its own min-content width. The page strip's min-content is
     496px, so on a 375px phone main came out 496 wide while the header stayed
     375, and the rail visibly fell short of the screen. A definite width
     removes the min-content floor; max-width still caps it and the auto
     margins still centre it. */
  width: 100%;
  background-color: var(--paper);
  box-shadow:
    0 0 0 1px rgba(120, 92, 50, 0.13),
    0 1px 1px rgba(58, 38, 12, 0.10),
    0 16px 34px -16px var(--cast);
  padding-block: 0.6rem 2.25rem;
  margin-bottom: 1.25rem;
}
/* Takes up whatever height is left over, so the plinth is always at the floor
   of the window rather than halfway up it on a short page. */
main { flex: 1 0 auto; }
main.wrap::before, .leaf::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background-image: var(--tex-fibre);
  background-size: 200px 200px;
  opacity: 0.045;
}
@media (min-width: 46rem) {
  main.wrap, .leaf {
    max-width: calc(var(--measure) + 5rem);
    padding-inline: 2.5rem;
    margin-block: 1.6rem 2.75rem;
  }
}

/* The shelf page is a room, not a column: it manages its own measure with
   inner .wrap divs and needs the full viewport for the furniture. */
.shelf-main { max-width: none; margin: 0; padding: 0; }

/* ---- site chrome: an oak rail across the top of the room ----
   Still the theme's cream, but now a piece of the furniture: a lit top arris,
   grain running the length of it, a darkening toward the bottom edge and a
   brass bead where it meets the page. isolation:isolate keeps the grain layer
   (z-index:-1) above the rail's own colour and below its links, without every
   child having to opt into a stacking order. */
.site-header {
  position: relative;
  isolation: isolate;
  background:
    linear-gradient(180deg,
      var(--wood-lit) 0%, var(--wood-face) 42%,
      var(--wood-edge) 88%, var(--wood-dark) 100%);
  border-bottom: 0;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.55),
    0 5px 14px -6px var(--cast);
}
.site-header::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background-image: var(--tex-wood);
  background-size: 780px 100%;
  opacity: 0.16;
  mix-blend-mode: multiply;
}
/* The bead. Two pixels of brass is the whole difference between a coloured
   band and a piece of trim. */
.site-header::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: linear-gradient(180deg, var(--brass-lit), var(--brass));
  opacity: 0.85;
}
.site-title { text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); }
/* On wood, a cream hairline vanishes; these controls take their edge from the
   grain around them instead. */
.site-header .theme-toggle {
  border-color: rgba(88, 62, 26, 0.35);
  background: rgba(255, 250, 240, 0.35);
}
.site-header .wrap-wide {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; padding-block: 0.85rem;
}
.site-title {
  font-weight: 700; font-size: 1.4rem; color: var(--ink);
  text-decoration: none; letter-spacing: -0.01em;
}
.site-title:visited { color: var(--ink); }
.site-nav {
  display: flex; align-items: center; gap: 1.1rem; font-size: 0.95rem;
  overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.site-nav::-webkit-scrollbar { display: none; }
.site-nav a { white-space: nowrap; }
/* The main site's own menu items. Hidden on narrow screens, where five long
   Devanagari labels would crowd out the two links that belong to this part of
   the site — the footer keeps a full set for those readers. */
@media (max-width: 60rem) { .site-nav .nav-main { display: none; } }
.site-nav a { color: var(--ink); text-decoration: none; }
.site-nav a:visited { color: var(--ink); }
.site-nav a:hover { color: var(--accent); }

/* The search link in the header. Sized to the same target as the theme toggle
   beside it, so the two read as a pair of controls rather than a link and a
   button. */
.nav-search {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2rem; height: 2rem; flex: none; border-radius: 999px;
}
.nav-search svg {
  width: 1.15rem; height: 1.15rem;
  fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round;
}
.nav-search:hover { color: var(--accent); background: rgba(255, 250, 240, 0.45); }

.theme-toggle {
  background: transparent; border: 1px solid var(--rule); border-radius: 999px;
  color: var(--ink); cursor: pointer; font: inherit; font-size: 0.9rem;
  padding: 0.15rem 0.6rem; line-height: 1.6;
}
.theme-toggle:hover { border-color: var(--accent); color: var(--accent); }
.theme-toggle .t-dark { display: none; }
:root[data-theme="dark"] .theme-toggle .t-dark { display: inline; }
:root[data-theme="dark"] .theme-toggle .t-light { display: none; }


.breadcrumbs {
  font-size: 0.85rem; color: var(--ink-soft);
  padding: 1rem 0 0.25rem; margin: 0;
  list-style: none; display: flex; flex-wrap: wrap; gap: 0.35rem;
}
.breadcrumbs a { color: var(--ink-soft); }
.breadcrumbs li::after { content: "›"; margin-left: 0.35rem; color: var(--rule); }
.breadcrumbs li:last-child::after { content: ""; }

h1 {
  font-size: 1.65rem; font-weight: 600; line-height: 1.35;
  color: var(--accent); margin: 0.4rem 0 0.3rem;
}
h2 { font-weight: 600; }
.subtitle { color: var(--ink-soft); font-size: 0.92rem; margin: 0 0 1.25rem; }

/* ---- reading position ---- */
.progress {
  height: 3px; background: var(--rule); border-radius: 2px;
  overflow: hidden; margin: 0 0 0.85rem;
}
.progress > span { display: block; height: 100%; background: var(--accent); }

/* ---- page strip: one tap to any page in this window ---- */
/* Bled out to the leaf's own edges. Inset, the sticky strip left two strips
   of un-blurred paper down either side with the text scrolling up through
   them. The negative margin has to track the leaf's padding at both widths. */
.page-strip {
  position: sticky; top: 0; z-index: 20;
  background: color-mix(in srgb, var(--paper) 92%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--rule);
  padding: 0.5rem 1.15rem; margin: 0 -1.15rem 0.5rem;
}
@media (min-width: 46rem) {
  .page-strip { padding-inline: 2.5rem; margin-inline: -2.5rem; }
}
.page-strip ol {
  display: flex; align-items: stretch; gap: 0.3rem; overflow-x: auto;
  list-style: none; margin: 0; padding: 0 0 2px;
  scrollbar-width: none;
}
.page-strip ol::-webkit-scrollbar { display: none; }
.page-strip a {
  /* Centred by the box, not by padding: the serif's digit metrics sit above
     the em box's middle, so symmetric padding leaves the number riding high. */
  display: flex; align-items: center; justify-content: center;
  min-width: 2.6rem; min-height: 2rem; padding: 0 0.55rem;
  line-height: 1; text-decoration: none;
  border: 1px solid var(--rule); border-radius: 999px;
  font-size: 0.85rem; font-variant-numeric: tabular-nums;
  color: var(--ink-soft); background: var(--paper-card);
}
.page-strip a:visited { color: var(--ink-soft); }
.page-strip a:hover, .page-strip a:focus-visible {
  border-color: var(--accent); color: var(--accent);
}

/* ---- a page of the book ---- */
.page { border-top: 1px solid var(--rule); padding-top: 1.35rem; margin-top: 1.75rem; }
.page:first-of-type { border-top: 0; margin-top: 0.75rem; }

.page > h2 {
  font-size: 0.76rem; font-weight: 600; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--ink-soft);
  margin: 0 0 0.85rem;
}
.page > h2 a { color: inherit; text-decoration: none; }
.page > h2 a:visited { color: inherit; }
.page > h2 a:hover { color: var(--accent); }

.page:target > h2 { color: var(--accent); }
.page:target { animation: flash 1.8s ease-out; }
@keyframes flash {
  from { background: var(--paper-warm); }
  to   { background: transparent; }
}

/* Verse is set apart by its own ground rather than a rule in the margin:
   a warm bubble, slightly larger and bolder, which is closer to how a doha
   actually sits on the printed page. */
.verse {
  margin: 1.4rem 0;
  padding: 1rem 1.15rem;
  background: var(--verse-bg);
  border: 1px solid var(--verse-edge);
  border-radius: 12px;
  color: var(--verse-ink);
  font-size: 1.16rem;
  font-weight: 600;
  /* Tighter than the prose around it. A doha is two padas that belong
     together; generous leading pulls them apart into separate thoughts.
     1.75 still clears the matras above and below comfortably. */
  line-height: 1.75;
  letter-spacing: 0.005em;
}
.verse p { margin: 0.15rem 0; text-wrap: pretty; }
.verse p:first-child { margin-top: 0; }
.verse p:last-child { margin-bottom: 0; }

.prose p { margin: 1rem 0; }

@media (min-width: 40rem) {
  .verse { padding: 1.15rem 1.5rem; font-size: 1.22rem; line-height: 1.8; }
}

mark { background: var(--mark); color: inherit; padding: 0 0.12em; border-radius: 2px; }

/* A match the reader arrived on from search, as opposed to one we chose to
   emphasise ourselves. Green rather than the amber above so that landing on a
   page from a search result looks different from reading it — and so the eye
   finds the word without being told where to look. */
mark.hit {
  background: var(--hit-bg);
  color: var(--hit-ink);
  box-shadow: 0 0 0 1px var(--hit-ring) inset;
  padding: 0 0.16em;
  border-radius: 3px;
}
/* The dark theme repaints plain <mark> ink, and does it with a selector that
   outranks .hit — so .hit has to be restated inside it or the green box gets
   near-black text on a dark green ground. */
:root[data-theme="dark"] mark.hit { color: var(--hit-ink); }

/* ---- the scan leads; the text follows underneath ----------------------
   The two are given different grounds on purpose. A scan is a photograph of
   paper and wants a frame; the transcription is our own text and wants the
   page's own surface. Without that separation a long window reads as one
   undifferentiated column of alternating grey and white blocks. */

.page-scan {
  margin: 0;
  padding: 0.6rem;
  background: var(--scan-mat);
  border: 1px solid var(--rule);
  border-radius: 8px;
  cursor: zoom-in;
  /* Cut into the leaf rather than laid on top of it: a mount holds a print
     down, it does not float above the page. */
  box-shadow:
    inset 0 1px 3px rgba(58, 38, 12, 0.16),
    0 1px 0 rgba(255, 255, 255, 0.65);
}
.page-scan picture { display: block; }
.page-scan img {
  display: block;
  /* Sized by its own aspect, not forced to the container. width:100% with a
     max-height and object-fit:contain makes the BOX full-width and letterboxes
     the page inside it — the leftover box is the dead strip that showed under
     the scan. Constraining both axes and letting the image pick its own size
     means the frame always fits the page exactly. */
  width: auto;
  height: auto;
  max-width: 100%;
  /* Capped so the expander below is on screen with the scan: the reader should
     see there is text, not have to scroll to discover it. */
  max-height: 74svh;
  margin-inline: auto;
  background: #f7f3ea;
  border-radius: 3px;
  /* The print sits proud of its mount. */
  box-shadow: 0 1px 3px rgba(58, 38, 12, 0.32);
}
.page-scan figcaption {
  text-align: center; font-size: 0.72rem; color: var(--ink-soft);
  padding-top: 0.5rem; letter-spacing: 0.02em;
}

/* Desktop: a page of a book is taller than it is wide, so filling the width of
   a large screen blows it up past legibility and past the fold. Constrain by
   height instead and let the width follow, which shows the whole page at once.
   Gated at 64rem so phone landscape and tablets keep the fill-width behaviour
   that suits them. */
@media (min-width: 64rem) {
  .page-scan img { max-height: 82vh; }
}

/* ---- the transcription ---- */
.page-text { margin: 0.9rem 0 0; }
.page-text > summary {
  cursor: pointer; list-style: none; user-select: none;
  display: inline-flex; align-items: center; gap: 0.45rem;
  font-size: 0.85rem; color: var(--ink-soft);
  padding: 0.4rem 0.95rem;
  border: 1px solid var(--rule); border-radius: 999px;
  background: var(--paper-card);
}
.page-text > summary::-webkit-details-marker { display: none; }
.page-text > summary::before { content: "¶"; color: var(--accent); font-weight: 700; }
.page-text > summary:hover { border-color: var(--accent); color: var(--accent); }
.page-text > summary .open { display: none; }
.page-text[open] > summary .open { display: inline; }
.page-text[open] > summary .closed { display: none; }
.page-text-body {
  margin-top: 0.9rem; padding: 0.1rem 0.15rem 0.2rem;
  border-top: 1px solid var(--rule);
}

/* The reader's own view choice, above the page strip. */
.view-controls { display: flex; justify-content: flex-end; margin: 0.25rem 0 0.4rem; }
.view-toggle {
  background: var(--paper-card); border: 1px solid var(--rule); border-radius: 999px;
  color: var(--ink-soft); cursor: pointer; font: inherit; font-size: 0.8rem;
  padding: 0.25rem 0.85rem;
}
.view-toggle:hover { color: var(--accent); border-color: var(--accent); }
.view-toggle .on-open { display: none; }
.view-toggle.is-open .on-open { display: inline; }
.view-toggle.is-open .on-closed { display: none; }

/* ---- back to top, with a reading-progress ring ---- */
.to-top {
  position: fixed; right: 1.1rem; bottom: 1.1rem; z-index: 60;
  width: 50px; height: 50px; border-radius: 50%;
  background: var(--totop-bg); color: var(--totop-ink);
  box-shadow: inset 0 0 0 2px #fff, 0 2px 10px rgba(0,0,0,0.25);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; opacity: 0; pointer-events: none;
  transition: opacity 0.2s linear;
  padding-bottom: env(safe-area-inset-bottom);
}
.to-top.is-visible { opacity: 1; pointer-events: auto; }
.to-top .progress-circle { position: absolute; inset: 0; }
.to-top .progress-circle path {
  fill: none; stroke: var(--totop-ring); stroke-width: 4px;
  transition: stroke-dashoffset 0.2s linear;
}
.to-top .chev { font-size: 0.8rem; line-height: 1; }

/* ---- legacy inline scan toggle (kept for pages built before the change) ---- *//* ---- legacy inline scan toggle (kept for pages built before the change) ---- */
.scan { margin: 1.2rem 0 0; }
.scan > summary {
  cursor: pointer; display: inline-flex; align-items: center; gap: 0.45rem;
  font-size: 0.86rem; color: var(--ink-soft);
  padding: 0.4rem 0.85rem; border: 1px solid var(--rule); border-radius: 999px;
  background: var(--paper-card); list-style: none; user-select: none;
}
.scan > summary::-webkit-details-marker { display: none; }
.scan > summary::before { content: "◧"; color: var(--accent); }
.scan > summary:hover { border-color: var(--accent); color: var(--accent); }
.scan img {
  display: block; width: 100%; height: auto; margin-top: 0.7rem;
  border: 1px solid var(--rule); border-radius: 4px; background: var(--paper-card);
}

/* ---- window to window ---- */
.pager {
  display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem;
  border-top: 1px solid var(--rule); margin-top: 2.75rem; padding-top: 1.4rem;
}
.pager a {
  display: block; padding: 0.85rem 1rem; text-decoration: none;
  border: 1px solid var(--rule); border-radius: 8px;
  background: var(--paper-card); color: var(--ink);
  font-size: 0.95rem; line-height: 1.5;
}
.pager a:visited { color: var(--ink); }
.pager a:hover { border-color: var(--accent); }
.pager .dir { display: block; font-size: 0.75rem; color: var(--ink-soft); letter-spacing: 0.05em; }
.pager .next { grid-column: 2; text-align: right; }
.pager .prev { grid-column: 1; }

/* ---- a book's title page ----
   Centred, ruled off, with a danda hung on the rule where a printed granth
   would set an ornament. The knockout behind the glyph is the leaf's own
   colour, so the rule appears to pass behind it. */
.title-page {
  position: relative; text-align: center;
  margin: 1.25rem 0 2.25rem; padding-bottom: 1.6rem;
  /* The rule is drawn, not bordered, so it can fade out at both ends and
     leave a gap in the middle for the ornament. A knocked-out background
     behind the glyph would have to match the leaf exactly, and the leaf
     carries a fibre layer — on the dark theme the mismatch showed as a pale
     rectangle sitting on the rule. */
  background-image: linear-gradient(90deg,
    transparent 0%, var(--rule) 14%, var(--rule) 44%,
    transparent 45%, transparent 55%,
    var(--rule) 56%, var(--rule) 86%, transparent 100%);
  background-size: 100% 1px;
  background-position: 0 100%;
  background-repeat: no-repeat;
}
.title-page h1 { color: var(--ink); margin-bottom: 0.5rem; }
.title-page .subtitle { margin-bottom: 0; }
.title-page::after {
  content: "॥";
  position: absolute; left: 50%; bottom: 0; transform: translate(-50%, 50%);
  color: var(--accent); font-size: 1.35rem; line-height: 1;
  letter-spacing: 0.1em;
}

/* ---- listings ----
   The contents page of a printed book: entry on the left, page column ruled
   off on the right, dotted leaders between the rows. The entries are OCR
   snippets rather than chapter titles, so they are clamped to two lines —
   a leader dot trailing off a four-line paragraph reads as a bug. */
.toc { list-style: none; padding: 0; margin: 1.25rem 0 0; }
.toc li { border-bottom: 1px dotted var(--rule); }
.toc-head {
  display: flex; justify-content: space-between;
  padding: 0 0.3rem 0.45rem;
  font-size: 0.7rem; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-soft);
  border-bottom: 1px solid var(--rule);
}
/* The page column is a fixed width, not auto: every row is its own grid, so
   an auto column would size to that row's own range and the numbers would
   step in and out down the page instead of lining up. 5.5rem holds the widest
   range a book of this corpus produces — "2251–2256" — on one line. */
.toc a {
  display: grid; grid-template-columns: 1fr 5.5rem; gap: 0 1rem;
  align-items: baseline;
  padding: 0.8rem 0.3rem; text-decoration: none; color: var(--ink);
}
.toc a:visited { color: var(--ink); }
.toc a:hover { background: var(--paper-warm); }
.toc .entry {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: 0.95rem; line-height: 1.6;
}
.toc .range {
  text-align: right; white-space: nowrap;
  font-variant-numeric: tabular-nums; color: var(--accent);
  font-size: 0.85rem; letter-spacing: 0.04em;
}
.toc-heading { font-size: 1.25rem; margin-bottom: 0.25rem; }

/* The catalogue: the same books filed flat, each showing the edge of its own
   binding down the left margin. It is the crawlable, keyboard-navigable list
   the shelf carousel is a nicer way of browsing — never the only way in. */
.book-card {
  display: block; padding: 1.1rem 0; border-bottom: 1px solid var(--rule);
  text-decoration: none; color: var(--ink);
}
.book-card:visited { color: var(--ink); }
.book-card h2 { margin: 0 0 0.25rem; font-size: 1.2rem; color: var(--link); }
.book-card:hover h2 { color: var(--accent); }
.book-card p { margin: 0; color: var(--ink-soft); font-size: 0.9rem; }

.catalogue .book-card { position: relative; padding-inline-start: 1.6rem; }
.catalogue .book-card::before {
  content: ""; position: absolute; left: 0; top: 0.9rem; bottom: 0.9rem;
  width: 0.45rem; border-radius: 1px;
  background: linear-gradient(90deg,
    rgba(0, 0, 0, 0.4) 0%, var(--spine, var(--accent)) 42%,
    rgba(255, 255, 255, 0.28) 100%);
  box-shadow: 0 1px 2px rgba(58, 38, 12, 0.4);
}

/* ---- search ---- */
.search-form { display: flex; gap: 0.5rem; margin: 1.5rem 0; }
.search-form input {
  flex: 1; padding: 0.75rem 1rem; font: inherit; color: var(--ink);
  background: var(--paper-card); border: 1px solid var(--rule); border-radius: 999px;
}
.search-form input:focus-visible { outline: 2px solid var(--accent); border-color: var(--accent); }
.search-form button {
  padding: 0.75rem 1.4rem; font: inherit; cursor: pointer; color: #fff;
  background: var(--accent); border: 0; border-radius: 999px; font-weight: 600;
}
.result-group {
  font-size: 0.78rem; font-weight: 600; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--ink-soft);
  margin: 2rem 0 0.25rem; padding-bottom: 0.4rem;
  border-bottom: 2px solid var(--accent);
}
.result-group:first-child { margin-top: 1rem; }
.result { padding: 1.1rem 0; border-bottom: 1px solid var(--rule); }
.result-blog h3 a { color: var(--link); }
.result h3 { margin: 0 0 0.3rem; font-size: 1.05rem; font-weight: 600; }
.result h3 a { text-decoration: none; }
.result .meta { font-size: 0.78rem; color: var(--ink-soft); margin: 0 0 0.45rem; }
.result .excerpt { margin: 0; color: var(--ink); }
.search-status { color: var(--ink-soft); font-size: 0.9rem; }
.noscript-note {
  background: var(--paper-warm); border: 1px solid var(--rule);
  border-radius: 8px; padding: 0.85rem 1.1rem; font-size: 0.9rem;
}

/* The plinth: the same oak as the rail, lit from the other side because it is
   the bottom of the room rather than the top. */
.site-footer {
  position: relative;
  isolation: isolate;
  border-top: 0; margin-top: 0;
  padding-block: 1.75rem; font-size: 0.85rem; color: var(--ink-soft);
  background:
    linear-gradient(180deg,
      var(--wood-dark) 0%, var(--wood-edge) 3%,
      var(--wood-face) 30%, var(--wood-lit) 100%);
  box-shadow: inset 0 6px 12px -8px var(--cast);
}
.site-footer::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background-image: var(--tex-wood);
  background-size: 780px 100%;
  opacity: 0.16;
  mix-blend-mode: multiply;
}
.site-footer::after {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 2px;
  background: linear-gradient(0deg, var(--brass-lit), var(--brass));
  opacity: 0.85;
}
.site-footer p, .site-footer a { color: var(--ink); }
.site-footer p { opacity: 0.75; }
.footer-nav {
  display: flex; flex-wrap: wrap; gap: 0.5rem 1.25rem;
  list-style: none; margin: 0 0 1rem; padding: 0;
}
.footer-nav a { color: var(--ink); text-decoration: none; }
.footer-nav a:visited { color: var(--ink); }
.footer-nav a:hover { color: var(--accent); text-decoration: underline; }

/* ========================================================================
   Full-screen scan reader (progressive enhancement over <details>)
   ======================================================================== */

html.sv-open, html.sv-open body { overflow: hidden; }

.scan-viewer {
  position: fixed; inset: 0; z-index: 100; height: 100dvh;
  display: none; flex-direction: column;
  /* Dark enough that the page is the only lit thing on the screen, but grained
     rather than flat: the reader is holding the book up in the same room. */
  background-color: #14100b;
  background-image: var(--tex-wood);
  background-size: 620px 100%;
  background-blend-mode: overlay;
  color: #f3ece0;
}
.scan-viewer.is-open { display: flex; }

.sv-bar {
  display: flex; align-items: center; gap: 0.75rem;
  padding: 0.6rem 0.9rem;
  background: rgba(0, 0, 0, 0.55);
  font-size: 0.9rem;
  padding-top: max(0.6rem, env(safe-area-inset-top));
}
/* Which book you are in should never be a thing you have to remember. */
.sv-title {
  font-weight: 600; max-width: 42vw; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; color: #f6efe0;
}
.sv-title::after { content: "·"; margin: 0 0.15rem 0 0.5rem; color: #8b7e6a; }
.sv-count { font-variant-numeric: tabular-nums; color: #cbbfa9; }
@media (max-width: 26rem) { .sv-title { max-width: 34vw; font-size: 0.85rem; } }
.sv-hint {
  margin-inline: auto; font-size: 0.8rem; color: #c9bda8;
  opacity: 0; transition: opacity 0.35s;
}
.scan-viewer.show-hint .sv-hint { opacity: 1; }
.sv-close {
  margin-left: auto; background: transparent; border: 0; cursor: pointer;
  color: #f3ece0; font-size: 1.35rem; line-height: 1; padding: 0.25rem 0.5rem;
}

/* Native scroll-snap does the swiping: momentum, rubber-banding and
   pinch-zoom all behave the way the platform does. */
.sv-track {
  flex: 1; display: flex; overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none; outline: none;
  overscroll-behavior-x: contain;
}
.sv-track::-webkit-scrollbar { display: none; }

.sv-slide {
  flex: 0 0 100%;
  scroll-snap-align: center;
  scroll-snap-stop: always;
  /* margin:auto on the figure, not place-items:center on the slide: it centres
     a short page AND top-aligns a tall one, where centring would clip the top
     out of reach in a scroll container. This is what left a strip of dead
     space under the page before. */
  display: flex;
  /* Each page is its own vertical scroller inside the horizontal track. Nested
     scrolling is resolved by the browser from the direction of the gesture, so
     a sideways swipe turns the page and an upward one reads further down it. */
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: 0.4rem;
}
.sv-slide figure { margin: auto; width: 100%; }
.sv-slide img {
  display: block;
  /* Fill the width and let height follow. The old cap of (100dvh - 8.5rem)
     made sense in portrait and was ruinous in landscape, where the viewport is
     short: the page shrank to a stamp in the middle of the screen exactly when
     the reader had turned the phone to make it bigger. */
  width: 100%;
  height: auto;
  background: #efe9de;
  border-radius: 3px;
  /* No touch-action override. `pinch-zoom` alone told the browser this element
     handles nothing but zoom, so horizontal swipes never reached the track and
     the page would only turn if you swiped the black margin below it. */
}

.sv-nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  background: rgba(0,0,0,0.45); color: #f3ece0; border: 0; cursor: pointer;
  font-size: 2rem; line-height: 1; padding: 0.45rem 0.7rem; border-radius: 6px;
}
.sv-nav:disabled { opacity: 0.25; cursor: default; }
.sv-prev { left: 0.4rem; }
.sv-next { right: 0.4rem; }
@media (hover: none) { .sv-nav { display: none; } }   /* swipe instead */

.sv-foot {
  padding: 0.7rem 0.9rem; text-align: center;
  background: rgba(0,0,0,0.55); font-size: 0.9rem;
  padding-bottom: max(0.7rem, env(safe-area-inset-bottom));
}
.sv-foot a { color: var(--accent); text-decoration: none; }
.sv-foot a:visited { color: var(--accent); }

/* Landscape on a phone: every pixel of height is reading space. */
@media (max-height: 30rem) and (orientation: landscape) {
  .sv-bar { padding-block: 0.25rem; font-size: 0.8rem; }
  .sv-foot { padding-block: 0.3rem; font-size: 0.8rem; }
  .sv-slide { padding: 0.2rem; }
}

/* Desktop viewer: show the whole page, as on the reading page. */
@media (min-width: 64rem) {
  .sv-slide figure { width: auto; }
  .sv-slide img { width: auto; max-width: 100%; max-height: calc(100dvh - 7rem); }
}

@media (min-width: 40rem) {
  body { font-size: 1.1rem; }
  h1 { font-size: 2rem; }
  .page-strip a { min-width: 2.9rem; }
}


/* ---- dark-mode refinements ----
   On a dark ground a hard border reads as an outline drawn around the verse;
   a lifted surface reads as the verse sitting on its own leaf. Bold type also
   blooms on dark, so the bubble carries a touch less contrast than its light
   counterpart rather than more. */

:root[data-theme="dark"] .verse {
  box-shadow: 0 1px 0 rgba(255, 236, 200, 0.05) inset,
              0 2px 10px rgba(0, 0, 0, 0.35);
}
:root[data-theme="dark"] mark { color: #1a1408; }


/* @embed:start */
/* ========================================================================
   Library shelf — the corpus homepage
   The visual technique (scroll-snap track, proximity scale/rotate computed
   per frame from distance-to-viewport-centre) is adapted from a book-shelf
   carousel in a private tool of the owner's. Palette and card design are this
   site's own — warm cloth-bound spines rather than that tool's dark oklch
   theme — and every card is a real <a href>, not a button: the JS only adds
   motion, the link works and is crawlable with it off.
   ======================================================================== */

.shelf-hero { text-align: center; margin: 0.75rem 0 0.25rem; }
.shelf-hero h1 { color: var(--ink); margin-bottom: 0.15rem; }
.shelf-hero .subtitle {
  max-width: 34rem; margin-inline: auto; font-size: 0.85rem; margin-bottom: 0.6rem;
}
/* Toggle and arrows share one row on a phone. Stacked, they cost ~120px of
   height and pushed the shelf itself below the fold. */
.shelf-controls {
  display: flex; align-items: center; justify-content: center;
  gap: 0.6rem; flex-wrap: wrap; margin-bottom: 0.2rem;
}

/* Gilt stamping: a warm gradient clipped to the glyphs with a dark seat under
   them, so the letters read as pressed into the cloth rather than printed on. */
.shelf-body .cat, .shelf-body h2 {
  background: linear-gradient(180deg,#fff3cf 0%,#e6be6a 42%,#a97c2e 78%,#f0dca4 100%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 1px 0 rgba(0,0,0,0.55));
}

/* ---- the shelf carcass -------------------------------------------------
   Books were floating on the page background. Now they stand on something:
   a back panel of grained wood, and a board across the foot drawn as three
   bands — a foreshortened top face, a lit arris, and the front edge falling
   into the dark reveal underneath.

   The board is painted on .shelf, not on .shelf-track, and that is the whole
   trick: a background on a scroll container is fixed to its border box, so
   the books slide along a shelf that stays put. Painting it on the track
   would have dragged the furniture along with them.

   --board is the single number the geometry hangs off. The track's bottom
   padding is derived from it so the books' feet always land on the top face,
   whatever the breakpoint sets. */
.shelf {
  --board: 1.75rem;
  position: relative;
  isolation: isolate;
  margin-bottom: 0.35rem;
  background-color: var(--board-back);
  background-image:
    /* the ends of the shelf falling into shadow, so the row reads as
       continuing past the screen rather than stopping at it */
    linear-gradient(90deg, rgba(0,0,0,0.45) 0%, transparent 11%,
                           transparent 89%, rgba(0,0,0,0.45) 100%),
    var(--tex-wood),
    /* light falling from the top of the room, and the panel darkening into
       the corner where it meets the board */
    linear-gradient(180deg, rgba(0,0,0,0.5) 0%, rgba(255,255,255,0.06) 40%,
                            rgba(0,0,0,0.42) 100%);
  background-size: auto, 460px 100%, auto;
  background-blend-mode: normal, soft-light, normal;
  box-shadow: inset 0 14px 26px -14px rgba(0, 0, 0, 0.9);
  border-block: 1px solid rgba(0, 0, 0, 0.5);
}
.shelf::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0;
  height: var(--board); z-index: 2; pointer-events: none;
  background-image:
    /* what the books pool onto the board at their feet */
    linear-gradient(180deg, rgba(0,0,0,0.55) 0%, rgba(0,0,0,0) 30%),
    var(--tex-wood),
    linear-gradient(180deg,
      var(--board-top) 0%,    var(--board-top) 26%,
      var(--board-arris) 26%, var(--board-arris) 31%,
      var(--board-lit) 31%,   var(--board-shade) 70%,
      var(--board-shade) 70%, var(--board-shade) 90%,
      var(--board-reveal) 90%, var(--board-reveal) 100%);
  background-size: auto, 460px 100%, auto;
  background-blend-mode: normal, overlay, normal;
}

.shelf-track {
  display: flex; gap: 0.9rem;
  overflow-x: auto; scroll-snap-type: x mandatory;
  /* The side padding centres the active card. It has to be derived from the
     card width, not guessed: at calc(50% - 6.5rem) on a 375px screen only
     208px of track remained for a 176px card, so exactly one cover filled the
     phone and nothing suggested there was a shelf to scroll. */
  padding: 1.35rem calc(50% - 4.6rem) calc(var(--board) * 0.80);
  scrollbar-width: none; outline: none;
  perspective: 1200px;
}
.shelf-track::-webkit-scrollbar { display: none; }

.shelf-card {
  scroll-snap-align: center; flex: 0 0 9.2rem;
  height: 13.2rem; position: relative; text-decoration: none;
  display: block; border-radius: 2px 7px 7px 2px;
  /* Pivot at the foot, not the middle. The proximity effect scales distant
     books down; scaled about their centre their feet lifted off the board and
     the row read as floating. A book that is further away is shorter on the
     shelf, not hovering above it. */
  transform-origin: 50% 100%;
  will-change: transform, opacity;
  transition: transform 0.3s ease-out, opacity 0.3s ease-out;
  /* The board, its stacked page block, and two shadows on the shelf: a tight
     dark one right at the foot, which is what makes an object read as resting
     on a surface rather than hovering over it, and a soft one further out. */
  box-shadow:
    1px 0 0 0 rgba(255,255,255,0.10) inset,
    2px 3px 0 -1px #e8dcc4,
    4px 5px 0 -1px #d9cbb0,
    6px 7px 0 -1px #cabc9d,
    0 3px 3px -2px rgba(12, 7, 1, 0.85),
    0 10px 14px -7px rgba(12, 7, 1, 0.7),
    10px 16px 22px -6px rgba(30, 20, 8, 0.45);
}

/* Cloth-bound board: a fine weave built from two crossed hatchings over the
   book's own colour, plus a lighting gradient so the board looks curved rather
   than flat. */
.shelf-cover {
  position: absolute; inset: 0; border-radius: 2px 7px 7px 2px; overflow: hidden;
  border: 1px solid rgba(0,0,0,0.30);
  background-blend-mode: overlay, overlay, soft-light, normal;
}
.shelf-cover::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    repeating-linear-gradient(90deg, rgba(0,0,0,0.05) 0 1px, transparent 1px 3px),
    repeating-linear-gradient(0deg,  rgba(0,0,0,0.05) 0 1px, transparent 1px 3px),
    radial-gradient(120% 90% at 22% 12%, rgba(255,255,255,0.20), transparent 60%),
    linear-gradient(100deg, rgba(0,0,0,0.28) 0 4%, transparent 14% 86%, rgba(0,0,0,0.18) 100%);
}
/* Blind-stamped rule near the board edge, as on a cloth binding. */
.shelf-cover::after {
  content: ""; position: absolute; inset: 0.42rem 0.4rem 0.42rem 1.15rem;
  border: 1px solid rgba(255,255,255,0.16);
  border-radius: 2px;
  box-shadow: 0 1px 0 rgba(0,0,0,0.22) inset;
  pointer-events: none;
}

/* Spine: raised, with a rolled gutter shadow and two gilt bands. */
.shelf-card .spine {
  position: absolute; inset-block: 0; left: 0; width: 0.95rem; z-index: 2;
  border-radius: 2px 0 0 2px;
  box-shadow:
    inset -3px 0 6px rgba(0,0,0,0.45),
    inset 2px 0 0 rgba(255,255,255,0.18),
    inset -1px 0 0 rgba(0,0,0,0.35);
}
.shelf-card .spine::before, .shelf-card .spine::after {
  content: ""; position: absolute; left: 1px; right: 0; height: 4px;
  background: linear-gradient(180deg,
    rgba(255,255,255,0.34), rgba(212,170,86,0.55) 45%, rgba(0,0,0,0.42));
}
.shelf-card .spine::before { top: 16%; }
.shelf-card .spine::after  { bottom: 16%; }

/* Head and tail bands, and the fore-edge page block. */
.shelf-card::before {
  content: ""; position: absolute; z-index: 3; left: 0.95rem; right: 2px;
  top: 0; height: 3px; border-radius: 0 2px 0 0;
  background: repeating-linear-gradient(90deg,#f4e7cc 0 2px,#b9905a 2px 4px);
  opacity: 0.85;
}
.shelf-card::after {
  content: ""; position: absolute; z-index: 3; right: 0; top: 3px; bottom: 3px;
  width: 4px; border-radius: 0 3px 3px 0;
  background: repeating-linear-gradient(180deg,#f6efdd 0 2px,#ddd0b4 2px 3px);
  box-shadow: inset -1px 0 2px rgba(0,0,0,0.25);
}

.shelf-cover .sheen {
  position: absolute; inset: 0; opacity: 0; z-index: 4;
  background: linear-gradient(112deg, transparent 26%, rgba(255,255,255,0.22) 46%, transparent 60%);
  transition: opacity 0.45s;
}
.shelf-card:hover .sheen { opacity: 1; }

.shelf-body {
  position: relative; height: 100%; padding: 1.1rem 0.9rem 0.85rem 1.35rem;
  display: flex; flex-direction: column; justify-content: flex-end; color: #fff;
}
.shelf-body .cat {
  position: absolute; top: 0.9rem; left: 1.35rem; right: 0.9rem;
  font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.16em;
  opacity: 0.8;
}
.shelf-body h2 {
  font-size: 1rem; font-weight: 700; line-height: 1.35; margin: 0 0 0.4rem;
  text-shadow: 0 1px 3px rgba(0,0,0,0.5);
}
.shelf-body .pages {
  font-size: 0.72rem; opacity: 0.85; display: flex; align-items: center; gap: 0.3rem;
}

.shelf-nav { display: flex; justify-content: center; gap: 0.5rem; margin: 0; }
.shelf-nav button {
  width: 2.1rem; height: 2.1rem; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--rule); background: var(--paper-card); color: var(--ink-soft);
  display: flex; align-items: center; justify-content: center; font-size: 1.1rem;
}
.shelf-nav button:hover { color: var(--accent); border-color: var(--accent); }
.shelf-nav button:disabled { opacity: 0.35; cursor: default; }

.shelf-caption {
  text-align: center; margin: 0.2rem 0 1.25rem; min-height: 1.3rem; font-size: 0.92rem;
}
.shelf-caption .t { color: var(--ink); font-weight: 600; }
.shelf-caption .c { color: var(--ink-soft); }

/* ---- finding a book on the shelf ---------------------------------------
   A different job from /search/, and deliberately a different mechanism: this
   filters the sixty cards already in the page, so it costs one pass over an
   array per keystroke and never touches the index. The corpus search reads a
   63MB index to find a phrase inside a book; this finds the book. */
.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

.shelf-tools { margin: 0.4rem auto 1.6rem; }

.shelf-find {
  position: relative;
  display: flex; align-items: center;
  background: var(--paper-card);
  border: 1px solid var(--rule); border-radius: 999px;
  box-shadow: 0 1px 2px rgba(58, 38, 12, 0.07) inset;
}
.shelf-find:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px #fc9c0d22; }
.shelf-find .find-icon {
  width: 1.05rem; height: 1.05rem; flex: none; margin-inline: 0.9rem 0;
  fill: none; stroke: var(--ink-soft); stroke-width: 2; stroke-linecap: round;
}
.shelf-find input {
  flex: 1; min-width: 0; font: inherit; font-size: 0.95rem;
  padding: 0.6rem 0.75rem; border: 0; background: transparent; color: var(--ink);
  border-radius: 999px;
}
.shelf-find input:focus-visible { outline: none; }
/* Safari draws its own clear button inside a type=search box; ours sits in the
   same place and two of them look like a mistake. */
.shelf-find input::-webkit-search-cancel-button { display: none; }
.find-clear {
  flex: none; margin-inline: 0 0.45rem; padding: 0.25rem 0.55rem;
  font: inherit; font-size: 0.9rem; line-height: 1; cursor: pointer;
  border: 0; border-radius: 999px; background: transparent; color: var(--ink-soft);
}
.find-clear:hover { color: var(--accent); }

.cat-chips {
  display: flex; flex-wrap: wrap; gap: 0.4rem;
  margin-top: 0.7rem;
}
.chip {
  font: inherit; font-size: 0.82rem; cursor: pointer;
  padding: 0.28rem 0.8rem; border-radius: 999px;
  border: 1px solid var(--rule); background: var(--paper-card); color: var(--ink-soft);
}
.chip:hover { border-color: var(--accent); color: var(--accent); }
.chip .n {
  font-variant-numeric: tabular-nums; font-size: 0.75rem;
  opacity: 0.65; margin-left: 0.15rem;
}
/* The chosen one is a pressed key, not a link: filled, not merely outlined. */
.chip.is-on {
  background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600;
}
.chip.is-on .n { opacity: 0.85; }
/* A category with nothing left in it under the current text filter. Kept in
   place rather than removed: chips that appear and vanish as you type are a
   moving target for the finger that is reaching for one. */
.chip[disabled] { opacity: 0.35; cursor: default; }
.chip[disabled]:hover { border-color: var(--rule); color: var(--ink-soft); }

.shelf-sort {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem;
  margin-top: 0.55rem;
}
.sort-label {
  font-size: 0.78rem; color: var(--ink-soft); letter-spacing: 0.04em;
  margin-right: 0.15rem;
}

/* The homepage embed. */
.vy-shelf-heading {
  /* The saffron the rest of the site puts on a heading, not the body ink. */
  text-align: center; margin: 0 0 0.7rem; font-size: 1.5rem; font-weight: 600;
  color: var(--accent); letter-spacing: 0.01em;
}
@media (min-width: 40rem) { .vy-shelf-heading { font-size: 1.9rem; } }
/* On the homepage the tools sit directly under the shelf with nothing between,
   so they need their own breathing room rather than the page's. */
.vy-shelf .shelf-tools { max-width: 44rem; margin-inline: auto; padding-inline: 1.15rem; }

.embed-nav { margin-top: 0.5rem; }
.embed-more { text-align: center; margin: 0.6rem 0 0; font-size: 0.95rem; }
.embed-more a { color: var(--link); text-decoration: none; font-weight: 600; }
.embed-more a:hover { color: var(--accent); text-decoration: underline; }

.find-empty {
  margin: 1rem 0 0; text-align: center; color: var(--ink-soft); font-size: 0.9rem;
}

/* Filtered out. display:none rather than visibility, so the scroll-snap track
   closes up around what is left instead of leaving gaps to scroll past. */
.shelf-card[hidden], .book-card[hidden] { display: none; }

/* All-books grid: what a crawler and a keyboard/screen-reader user actually
   navigate by. The carousel above is a nicer way to browse the same list,
   never the only way to reach it. */
.shelf-grid-heading {
  font-size: 0.78rem; font-weight: 600; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--ink-soft);
  margin: 2.5rem 0 1rem; padding-bottom: 0.4rem; border-bottom: 1px solid var(--rule);
}

@media (min-width: 40rem) {
  .shelf-hero { margin-top: 1.5rem; }
  .shelf-hero .subtitle { font-size: 0.92rem; }
  .shelf { --board: 2.4rem; }
  .shelf-track { gap: 1.5rem; padding: 2.75rem calc(50% - 8rem) calc(var(--board) * 0.80); }
  .shelf-card { flex-basis: 13.5rem; height: 19.5rem; }
.shelf-body h2 { font-size: 1.1rem; }
  .shelf-caption { margin-bottom: 2rem; }
}
/* @embed:end */
