/* ============================================================
   HOMEPAGE, BELOW THE FIRST SCREEN (owner, 2026-10-14: Speed Index). Split out of templates/index.html, which keeps
   inline only what the first screen needs (nav, hero, era rail, page frame). Served as /assets/home.<hash>.css and
   loaded with media="print" onload (a <noscript> link without scripts), so it never blocks the first paint. Rules
   keep their original order; a rule goes here only if it styles nothing in the first screen. The build fills in
   the italic font file's URL.
   ============================================================ */
/* The italic (closing headline, captions, demo foot): declared here so its file is not in the first screen's chain. */
@font-face{font-family:'Cormorant Garamond';font-style:italic;font-weight:400;font-display:swap;src:url(/assets/cormorant-garamond-italic.1f1787e2.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}

.nav ul a.active{opacity:1; color:var(--ink); border-color:var(--accent)}   /* the fixed nav's height: 2 x 22px padding + the brand's 26px x 1.55 line (84.3px); app.js checks it */
@media (min-width:901px){
  /* desktop: each slide is (stages beside it x --stage) tall, so each stage is the same scroll distance */
  [data-section="ebooksh"]{height:calc(var(--stages) * var(--stage))}
  /* the paperback shelf may grow past its runway instead of overlapping the next slide */
  [data-section="paperback"]{min-height:calc(var(--stages) * var(--stage))}
  /* two stages of runway (the scroll map starts 10vh early) plus most of a viewport, so the last stage completes */
  [data-section="closing"]{height:calc(2 * var(--stage) + 90svh)}
}
#ebooksh-demo{height:calc(var(--demo-layers) * var(--demo-layer) + 100svh)}
/* Phones: each artwork block sits in a slot sized to block + margins + runway, and is sticky
   (centred) for exactly the runway. The caption has a fixed height so the block's height is
   known: the tallest of the 16 captions at that width, measured 2026-09-24.
   The block never goes under the fixed nav: its top is at least --nav-h + 8px (the context
   chips sit on the artwork's top edge), and on a screen too short for that, the artwork
   shrinks so the whole block still fits below the nav (--art-w's third term). Centring alone,
   like the old pin's 'center center', put the chips under the nav on any phone viewport under
   ~800px tall (owner's Android finding, 2026-09-24). */
.m-slot{display:none}
@media (max-width:900px){
  .m-slot{display:flow-root; --cap:227px;
    --art-w:min(72vw, 360px, calc((100svh - var(--nav-h) - 16px - 4px - var(--cap)) * 3 / 4));
    --blk:calc(var(--art-w) * 4 / 3 + 4px + var(--cap));
    height:calc(6vh + var(--blk) + 4vh + var(--stages) * var(--stage))}
  .m-slot .m-art .artwork{width:var(--art-w)}
  .m-slot .m-art{position:sticky; top:max(calc(var(--nav-h) + 8px), calc(50svh - var(--blk) / 2))}
  .m-slot .caption{height:var(--cap); min-height:0}
}
@media (max-width:374.98px){ .m-slot{--cap:284px} }
@media (min-width:375px) and (max-width:389.98px){ .m-slot{--cap:258px} }
@media (min-width:600px) and (max-width:900px){ .m-slot{--cap:202px} }

/* ============================================================
   LEFT COLUMN MOTION: the static column's CSS equivalents of the Framer props it had in React
   (whileInView reveals, once; whileHover lifts). app.js adds .in via IntersectionObserver.
   Only with scripts (html.js, set in <head>), so the page is readable without them.
   ============================================================ */
html.js .rv{opacity:0; transform:translateY(var(--ry, 24px));
  transition:opacity var(--rt, .9s) cubic-bezier(.22,1,.36,1) var(--dl, 0s), transform var(--rt, .9s) cubic-bezier(.22,1,.36,1) var(--dl, 0s)}
html.js .rv.in{opacity:1; transform:none}
.rv-tile{--ry:12px; --rt:.6s}
.rv-fade{--ry:0px; --rt:.6s; --dl:.4s}
@media (hover:hover) and (prefers-reduced-motion:no-preference){ html.js .rv-tile.in:hover{transform:translateY(-3px)} }
@media (prefers-reduced-motion:reduce){ html.js .rv{opacity:1; transform:none; transition:none} }
.ctx-layer{position:absolute; inset:0; pointer-events:none}
.chip{position:absolute; display:flex; align-items:center; gap:9px; width:max-content; max-width:200px; padding:8px 12px 8px 9px; border-radius:999px; background:rgba(255,255,255,.55); border:1px solid var(--line); backdrop-filter:blur(4px); font-size:11.5px; line-height:1.3; color:var(--ink-2); box-shadow:0 10px 24px -16px rgba(23,21,18,.5); will-change:transform,opacity}
.chip svg{width:18px; height:18px; flex:0 0 18px; color:var(--accent-2)}
.chip.slot-a{left:-26%; top:2%}
.chip.slot-b{right:-30%; top:34%}
.chip.slot-c{left:-20%; bottom:8%}
.artwork > svg{width:100%; height:100%; overflow:visible; display:block}
.caption{margin-top:4px; text-align:center; min-height:170px}
.caption .era{font-size:12px; letter-spacing:.18em; text-transform:uppercase; color:var(--ink-2)}
.caption .name{font-family:var(--serif); font-size:28px; margin-top:6px; color:var(--ink)}
.caption .name.major{color:var(--ink)}
.caption .note{margin:14px auto 0; max-width:40ch; font-size:16px; font-weight:400; line-height:1.6; color:var(--ink-2); transition:opacity .45s ease}
.caption .note.swap,.caption .detail.swap{opacity:0}
.caption .detail{margin:12px auto 0; max-width:40ch; font-family:var(--serif); font-style:italic; font-size:20px; font-weight:500; color:var(--accent-2); transition:opacity .45s ease}
@media (prefers-reduced-motion:reduce){ .caption .note{transition:none} }   /* sections are five stages tall now: the content stays put while its stages play on the right */
.lede.small{font-size:15px; line-height:1.55; margin-top:14px; max-width:56ch; white-space:pre-line}
.eyebrow{font-size:11px; letter-spacing:.2em; text-transform:uppercase; color:var(--accent-2); margin-bottom:26px}
.headline em{font-style:italic; font-weight:400}
.h2{font-size:clamp(36px, 4.4vw, 68px); line-height:1.02; max-width:16ch}

/* genres */
.genres{display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); gap:0; margin-top:28px; max-width:640px; border-top:1px solid var(--line)}
.genre{padding:16px 4px; border-bottom:1px solid var(--line); display:flex; justify-content:space-between; align-items:baseline; font-family:var(--serif); font-size:26px; cursor:pointer}
.genre small{font-family:var(--sans); font-size:11px; letter-spacing:.14em; color:var(--ink-3); text-transform:uppercase}
.genre:nth-child(odd){border-right:1px solid var(--line); padding-right:24px}
.genre:nth-child(even){padding-left:24px}

/* book row */
.books{display:flex; gap:18px; margin-top:28px; align-items:flex-end}
.book{width:96px; aspect-ratio:2/3; border-radius:3px; position:relative; box-shadow:0 18px 40px -18px rgba(23,21,18,.45), 0 1px 0 rgba(255,255,255,.4) inset; cursor:pointer; overflow:hidden}
.book::after{content:""; position:absolute; inset:0; background:linear-gradient(90deg, rgba(0,0,0,.12), transparent 12%, transparent 88%, rgba(255,255,255,.18))}
.book .t{position:absolute; left:12px; right:12px; top:16px; font-family:var(--serif); font-size:15px; line-height:1.15; color:rgba(255,255,255,.92)}
.book .a{position:absolute; left:12px; bottom:14px; font-size:9px; letter-spacing:.12em; text-transform:uppercase; color:rgba(255,255,255,.7)}
.rail{display:flex; align-items:baseline; gap:14px; margin-bottom:14px}
.rail .eyebrow{margin:0; line-height:1}
.rail .mono{line-height:1}
.rail-line{flex:1; height:1px; background:linear-gradient(90deg, var(--line), transparent)}
.bento{display:grid; grid-template-columns:repeat(5, 1fr); grid-auto-rows:118px; gap:10px; margin-top:22px; max-width:720px}
.tile{position:relative; display:block; border-radius:14px; overflow:hidden; padding:14px; text-decoration:none; color:#fff; isolation:isolate;
  background:linear-gradient(160deg, color-mix(in srgb, var(--c) 92%, #fff) 0%, var(--c) 45%, color-mix(in srgb, var(--c) 55%, #171512) 100%);
  box-shadow:0 1px 0 rgba(255,255,255,.25) inset, 0 18px 40px -24px rgba(23,21,18,.55); border:1px solid rgba(255,255,255,.18)}
.tile::before{content:""; position:absolute; inset:0; background:radial-gradient(120% 80% at 20% 0%, rgba(255,255,255,.28), transparent 60%); pointer-events:none}
.tile::after{content:""; position:absolute; left:10px; right:10px; bottom:10px; height:1px; background:rgba(255,255,255,.22)}
/* Story tile art (build.mjs, from the story's thumb.svg): bottom-right, behind the title, on the tile colour. */
.tile-art{position:absolute; right:0; bottom:0; height:55%; width:auto; max-width:100%; z-index:-1; pointer-events:none}   /* aspect-ratio: from its viewBox, set by the build */
/* On the big tile the art stops 8px short of the Open button (right 16px + 78px wide), at every width: its width is
   what is left, its height follows the viewBox, capped at 55% of the tile (owner, 2026-10-14). */
.tile-big .tile-art{right:102px; width:calc(100% - 102px); height:auto; max-height:min(55%, 60px);   /* under the title (bottom:58px; its last line has no descenders) */
 
  -webkit-mask-image:linear-gradient(to right, #000 82%, transparent); mask-image:linear-gradient(to right, #000 82%, transparent)}   /* the cut ground fades out */
.tile-num{position:absolute; top:12px; right:14px; font-family:ui-monospace, Menlo, monospace; font-size:10px; letter-spacing:.1em; opacity:.7}
.tile-title{position:absolute; left:14px; right:14px; bottom:18px; font-family:var(--serif); font-size:15px; line-height:1.15; font-weight:500; text-shadow:0 1px 0 rgba(0,0,0,.15)}
.tile-big{grid-column:span 2; grid-row:span 2; border-radius:18px; padding:20px}
.tile-big .tile-title{font-size:30px; bottom:58px; left:20px; right:20px}
.tile-sub{position:absolute; left:20px; bottom:38px; font-size:11px; letter-spacing:.12em; text-transform:uppercase; opacity:.8}
.tile-cta{position:absolute; right:16px; bottom:14px; display:inline-flex; align-items:center; gap:6px; padding:8px 12px; border-radius:999px; background:rgba(255,255,255,.18); border:1px solid rgba(255,255,255,.35); backdrop-filter:blur(6px); font-size:11px; letter-spacing:.1em; text-transform:uppercase}
.tile-cta svg{width:11px; height:11px}
.index-rail{display:flex; justify-content:space-between; align-items:center; margin-top:16px; max-width:720px; padding-top:12px; border-top:1px solid var(--line)}
.index-rail .view-all{margin-top:0; border-bottom:0}
@media (max-width:900px){ .bento{grid-template-columns:repeat(3,1fr); grid-auto-rows:96px} .tile-big .tile-title{font-size:22px} }
/* thumbnails (legacy) */
.thumbs{display:grid; grid-template-columns:repeat(4, 88px); gap:16px 18px; margin-top:22px}
.thumb{display:block}
.thumb .cover{width:88px; aspect-ratio:2/3; border-radius:3px; position:relative; box-shadow:0 14px 28px -14px rgba(23,21,18,.5); overflow:hidden; padding:10px 9px}
.thumb .cover::after{content:""; position:absolute; inset:0; background:linear-gradient(90deg, rgba(0,0,0,.14), transparent 12%, transparent 88%, rgba(255,255,255,.16))}
.thumb .cover span{font-family:var(--serif); font-size:12px; line-height:1.15; color:rgba(255,255,255,.92); display:block}
.thumb .tt{margin-top:7px; font-size:12px; line-height:1.25; color:var(--ink-2); max-width:88px; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden}
.view-all{display:inline-flex; align-items:center; gap:8px; margin-top:18px; font-size:12px; letter-spacing:.12em; text-transform:uppercase; color:var(--ink); border-bottom:1px solid var(--accent); padding-bottom:4px}
.view-all svg{width:12px;height:12px}
.section .h2{font-size:clamp(30px, 2.6vw, 42px); max-width:22ch; letter-spacing:-.02em}
.section .eyebrow{margin-bottom:14px}

/* reading */
.reader{margin-top:32px; max-width:520px; background:var(--paper); padding:28px 32px; border-radius:6px; box-shadow:0 30px 60px -40px rgba(23,21,18,.5)}
.reader p{font-family:var(--serif); font-size:20px; line-height:1.7; color:var(--ink-2)}
.reader .prog{margin-top:28px; height:1px; background:var(--line); position:relative}
.reader .prog i{position:absolute; left:0; top:0; height:1px; width:38%; background:var(--accent)}
.reader .meta{display:flex; justify-content:space-between; font-size:11px; letter-spacing:.14em; text-transform:uppercase; color:var(--ink-3); margin-top:12px}
.qualities{display:flex; flex-wrap:wrap; gap:10px 28px; margin-top:26px; font-family:var(--serif); font-size:22px; color:var(--ink-2)}

/* library */
.shelf{margin-top:32px; display:grid; grid-template-columns:1.2fr 1fr; gap:36px; max-width:680px}
.lists{list-style:none; margin:0; padding:0; max-width:420px}
.lists li{display:flex; justify-content:space-between; padding:16px 0; border-bottom:1px solid var(--line); font-family:var(--serif); font-size:24px}
.lists li span{font-family:var(--sans); font-size:11px; letter-spacing:.14em; color:var(--ink-3); text-transform:uppercase}
.spines{display:flex; align-items:flex-end; gap:6px; height:200px; max-width:420px; border-bottom:2px solid var(--ink-2); padding-bottom:0}
.spine{width:22px; border-radius:2px 2px 0 0; box-shadow:inset -3px 0 6px rgba(0,0,0,.15)}

/* discovery */
.collections{margin-top:24px; display:grid; grid-template-columns:repeat(auto-fill, minmax(180px,1fr)); gap:10px; max-width:760px}
.coll{padding:18px 18px; border:1px solid var(--line); border-radius:6px; background:rgba(255,255,255,.35); font-family:var(--serif); font-size:21px; line-height:1.15; min-height:92px; display:flex; flex-direction:column; justify-content:space-between; cursor:pointer}
.coll small{font-family:var(--sans); font-size:10px; letter-spacing:.16em; text-transform:uppercase; color:var(--ink-3)}

/* final */
.final .headline{max-width:12ch; font-size:clamp(40px, 4.6vw, 72px)}
.final .lede{margin-top:12px; font-size:14px; line-height:1.5}
.final .ctas{margin-top:16px}
.final .headline{font-size:clamp(34px, 3.2vw, 50px)}
.final .lede{white-space:pre-line}
.final .section-inner{position:sticky; top:0; padding-top:18vh; min-height:100vh; box-sizing:border-box}
/* Desktop: centre the closing text vertically like the right column's .stage-sticky (same 10vh/4vh padding, flex
   centre), so it lines up with the final stage instead of sitting high above an empty block. The box stays 100vh,
   so the section height and every trigger are unchanged. (Infrastructure, owner-directed 2026-09-24) */
@media (min-width:901px){ .final .section-inner{display:flex; flex-direction:column; justify-content:center; padding:10vh 0 4vh} }
[data-section=demo] .section-inner{padding-top:22vh}
.next-chapter .headline{font-size:clamp(40px, 5.4vw, 88px); color:var(--ink-2); font-weight:400}

.footer{grid-column:1/-1; padding:60px var(--gutter); border-top:1px solid var(--line); display:flex; justify-content:space-between; font-size:12px; letter-spacing:.06em; color:var(--ink-3); flex-wrap:wrap; gap:16px}


/* ============================================================
   EBOOKSH DEMO (cell → dna)
   ============================================================ */
.demo{grid-column:1/-1; position:relative; border-top:1px solid var(--line); background:linear-gradient(180deg, var(--ivory), var(--paper))}
.demo-sticky{position:sticky; top:0; height:100vh; overflow:hidden; display:grid; grid-template-columns:var(--left-col) 1fr; align-items:start; padding:96px var(--gutter) 0; box-sizing:border-box}
.demo-art{align-self:center}
.demo-sticky .footer{position:absolute; left:0; right:0; bottom:0; padding:22px var(--gutter); grid-column:auto}
.demo-text{max-width:520px}
.demo-title{margin-bottom:18px; font-size:clamp(28px, 3vw, 44px)}
.demo-objects{position:relative; min-height:440px}
.demo-obj{position:absolute; inset:0; opacity:0}
.demo-obj h3{font-family:var(--serif); font-size:28px; font-weight:500}
.demo-obj p{margin-top:6px; color:var(--ink-2); font-size:15px}
.demo-obj ul{list-style:none; margin:14px 0 0; padding:0}
.demo-obj li{padding:3px 0 3px 22px; font-size:13.5px; border-left:1px solid var(--line); color:var(--ink-3); font-size:15px; position:relative; transition:color .3s}
.demo-obj li::before{content:""; position:absolute; left:-4px; top:15px; width:7px; height:7px; border-radius:50%; background:var(--line); transition:background .3s}
.demo-obj li.on{color:var(--ink)}
/* Compositor-only highlight (infrastructure, 2026-09-24): a 0.3s color transition can't run on the compositor
   (Lighthouse "non-composited animation"), so with scripts a lit layer crossfades two copies of its text by opacity:
   the grey text (wrapped in .t by app.js) fades out while a dark copy (::after, from data-t) fades in. Lit, only the dark
   copy shows, so the settled look is the same as the color it replaces. */
html.js .demo-obj li[data-t]{transition:none}
html.js .demo-obj li[data-t] .t{color:var(--ink-3); transition:opacity .3s}
html.js .demo-obj li[data-t].on .t{opacity:0}
html.js .demo-obj li[data-t]::after{content:attr(data-t); position:absolute; inset:0; padding:inherit; color:var(--ink); opacity:0; transition:opacity .3s; pointer-events:none}
html.js .demo-obj li[data-t].on::after{opacity:1}
.demo-obj li.on::before{background:var(--accent)}
.demo-foot{margin-top:14px; font-family:var(--serif); font-style:italic; font-size:20px; color:var(--accent-2)}
.demo-art{display:flex; justify-content:center; position:relative}
.demo-art .dna-scene{position:absolute; inset:0; margin:auto; width:min(100%, 80vh); height:min(100%, 80vh); opacity:0; overflow:visible; pointer-events:none}
.demo-art .cell-scene{position:absolute; inset:0; margin:auto; width:min(100%, 80vh); height:min(100%, 80vh); opacity:0; overflow:visible; pointer-events:none}
.demo-art svg{width:min(100%, 80vh); overflow:visible}
@media (min-width:901px){
  .bento.cover-bento{max-width:max(360px, calc((100svh - 440px) * 2.5))}   /* .bento.: outranks the later .cover-bento{max-width:none} */
  [data-section="paperback"] .cover-bento + .index-rail{max-width:max(360px, calc((100svh - 440px) * 2.5))}   /* its rail narrows with it (outranks the later max-width:none) */
}
@media (min-width:901px) and (max-height:899.98px){
  .demo-sticky{padding-bottom:64px; grid-template-rows:minmax(0, 1fr)}
  .demo-objects{display:grid; min-height:0} .demo-obj{position:relative; grid-area:1 / 1}
  .demo-title{font-size:clamp(24px, min(3vw, 5svh), 44px); margin-bottom:min(18px, 2svh)}
  .demo-obj h3{font-size:clamp(22px, 3.2svh, 28px)}
  .demo-obj ul{margin-top:min(14px, 1.6svh)}
  .demo-obj li{font-size:clamp(13px, 1.75svh, 15px); padding:clamp(0px, calc(1.2svh - 7px), 3px) 0 clamp(0px, calc(1.2svh - 7px), 3px) 22px}
  .demo-obj li::before{top:calc(clamp(0px, calc(1.2svh - 7px), 3px) + 12px)}
  .demo-foot{margin-top:min(14px, 1.6svh); font-size:clamp(17px, 2.3svh, 20px)}
  .demo-art svg, .demo-art .dna-scene, .demo-art .cell-scene{width:min(100%, 80vh, calc(100svh - var(--nav-h) - 11px - 64px - 16px))}
  .demo-art .dna-scene, .demo-art .cell-scene{height:min(100%, 80vh, calc(100svh - var(--nav-h) - 11px - 64px - 16px))}
}
@media (max-width:900px){
  .demo-sticky{grid-template-columns:1fr; grid-template-rows:auto 1fr; align-content:start; padding:84px var(--gutter) 60px; gap:6px}
  .demo-sticky{padding-bottom:104px}
  .demo-text{max-width:none}
  .demo-title{font-size:26px; margin-bottom:10px}
  .demo-objects{min-height:0; height:auto}
  .demo-obj{position:relative}
  .demo-objects{display:grid} .demo-obj{grid-area:1 / 1}
  .demo-obj:not(.active){visibility:hidden}   /* infrastructure (edit 17): was display:none; stacking keeps the text's height, and so the art's box, fixed */
  .demo-obj h3{font-size:22px}
  .demo-obj p{display:none}
  .demo-obj li{font-size:12px; padding:2px 0 2px 18px}
  .demo-foot{display:none}
  .demo-art{align-self:stretch; position:relative; min-height:0; max-height:42vh; overflow:hidden}
  .demo-art .dna-scene, .demo-art .cell-scene{width:100%; height:100%}
  .demo-art svg{width:min(80vw, 46vh)}
  .demo-objects{min-height:210px}
  .demo-obj h3{font-size:26px}
}
@media (max-width:900px){
  .hero + .section{padding-top:0}
  /* the desktop .final rule (sticky, padding-top 18vh, min-height 100vh) is more specific than .section-inner above:
     undo it so the closing section spaces like the others on phones: min-height left ~340px of empty viewport under
     the text, the 18vh added ~78px above the headline (infrastructure, owner-directed 2026-09-24; after the desktop rule, so it wins) */
  .final .section-inner{position:static; padding-top:8vh; min-height:0}
  .m-art{margin:6vh 0 4vh; display:flex; flex-direction:column; align-items:center; padding:0 var(--gutter)}
  .m-art .artwork{width:min(72vw, 360px)}
  .chip{max-width:150px; font-size:10.5px}
  .chip.slot-a{left:-6%}
  .chip.slot-b{right:-6%}
  .chip.slot-c{left:-2%}
  .genres{grid-template-columns:1fr}
  .genre:nth-child(odd){border-right:0; padding-right:4px}
  .genre:nth-child(even){padding-left:4px}
  .shelf{grid-template-columns:1fr}
  .books{overflow-x:auto; padding-bottom:12px}
  .thumbs{grid-template-columns:repeat(4, 1fr); gap:16px 10px}
  .thumb .cover{width:100%}
  .thumb .tt{max-width:100%}
  .book{flex:0 0 100px}
  .reader{padding:28px}
}

/* ---- paperback shelf: real covers ---- */
.shelf-grid{display:grid; grid-template-columns:repeat(4, 1fr); gap:26px 20px; margin-top:26px; max-width:760px}
.cover-card{display:block; text-decoration:none; color:inherit; position:relative}
.cover-card .shot{position:relative; border-radius:4px; overflow:hidden; background:var(--paper-2);
  box-shadow:0 18px 40px -20px rgba(23,21,18,.55), 0 1px 0 rgba(255,255,255,.35) inset;
  aspect-ratio:1/1; display:flex; align-items:center; justify-content:center}
.cover-card .shot img{width:100%; height:100%; object-fit:contain; display:block; background:var(--ink)}
.cover-card .shot::after{content:""; position:absolute; inset:0; pointer-events:none;
  background:linear-gradient(90deg, rgba(0,0,0,.16), transparent 10%, transparent 90%, rgba(255,255,255,.14))}
.cover-card .num{position:absolute; top:8px; left:8px; z-index:2; font-family:ui-monospace,Menlo,Consolas,monospace;
  font-size:10px; letter-spacing:.06em; color:rgba(255,255,255,.85); background:rgba(23,21,18,.45);
  padding:2px 6px; border-radius:20px; backdrop-filter:blur(4px)}
.cover-card .ct{margin-top:10px; font-family:var(--serif); font-size:16px; line-height:1.2; color:var(--ink)}
.cover-card .cs{margin-top:3px; font-size:11px; line-height:1.35; color:var(--ink-3)}
.cover-card .cb{margin-top:6px; font-size:12px; line-height:1.4; color:var(--ink-2); display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden}
.cover-card .cgo{margin-top:8px; font-size:10px; letter-spacing:.14em; text-transform:uppercase; color:var(--accent-2); opacity:0; transition:opacity .25s ease}
.cover-card:hover .cgo{opacity:1}
@media (max-width:1100px){ .shelf-grid{grid-template-columns:repeat(3, 1fr)} }
@media (max-width:860px){
  .shelf-grid{grid-template-columns:repeat(2, 1fr); gap:20px 14px}
  .cover-card .cb{-webkit-line-clamp:2}
}

/* ============================================================
   COVER BENTO (paperback shelf). Infrastructure-authored, owner-approved on preview
   versions 2026-09-23 (SPEC known debt; contract §5.2 edit 11). Reuses .bento's grid and gap
   and .tile's radii; Tile/.tile are untouched. Covers are never cropped (contain on --ink).
   ============================================================ */
.cover-bento{grid-auto-rows:auto; max-width:none}   /* max-none: fill the column (.bento's 720px cap only bit above ~1440px) */
.cbt{position:relative; display:block; border-radius:14px; overflow:hidden; aspect-ratio:1/1; background:var(--ink);
  box-shadow:0 18px 40px -24px rgba(23,21,18,.55); text-decoration:none; color:inherit}
.cbt img{position:absolute; inset:0; width:100%; height:100%; object-fit:contain; display:block; background:var(--ink)}
.cbt-big{grid-column:span 2; grid-row:span 2; aspect-ratio:auto; border-radius:18px}
/* Small tiles, phone widths: title revealed on hover/focus in a paper panel */
.cbt .cap{position:absolute; left:0; right:0; bottom:0; padding:10px 12px 12px; background:rgba(247,242,232,.94); backdrop-filter:blur(6px);
  opacity:0; transform:translateY(6px); transition:opacity .25s ease, transform .25s ease}
.cbt:hover .cap, .cbt:focus-visible .cap{opacity:1; transform:none}
.cbt .cap .ct{margin-top:0; font-family:var(--serif); font-size:16px; line-height:1.2; color:var(--ink)}
.cbt .cap .cs{margin-top:3px; font-size:11px; line-height:1.35; color:var(--ink-3)}
/* Small tiles, above the mobile breakpoint: a bottom band, not an overlay. Container units keep the band
   within ~35% of the tile at any tile width (2 lines at 2.3 x font + padding). */
@media (min-width:901px){
  .cbt:not(.cbt-big){container-type:inline-size}
  .cbt:not(.cbt-big) .cap{max-height:35%; overflow:hidden; padding:5cqw 7cqw 4cqw; backdrop-filter:none;
    background:linear-gradient(to top, rgba(23,21,18,.88) 0%, rgba(23,21,18,.72) 55%, rgba(23,21,18,0) 100%)}
  .cbt:not(.cbt-big) .cap .ct{font-size:clamp(10px, 11cqw, 14px); line-height:1.15; color:#fff; text-shadow:0 1px 2px rgba(0,0,0,.45);
    display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden}
}
/* Big tile, every width: the same band, always visible (works without hover), <=35% of the tile,
   title + subtitle on one line each */
.cbt-big{container-type:inline-size}
.cbt-big .cap{opacity:1; transform:none; max-height:35%; overflow:hidden; padding:9cqw 5cqw 4cqw; backdrop-filter:none;
  background:linear-gradient(to top, rgba(23,21,18,.88) 0%, rgba(23,21,18,.72) 55%, rgba(23,21,18,0) 100%)}
.cbt-big .cap .ct, .cbt-big .cap .cs{white-space:nowrap; overflow:hidden; text-overflow:ellipsis; color:#fff; text-shadow:0 1px 2px rgba(0,0,0,.45)}
.cbt-big .cap .ct{font-size:clamp(14px, 7cqw, 22px); line-height:1.15}
.cbt-big .cap .cs{font-size:clamp(10px, 4cqw, 12px); color:rgba(255,255,255,.82)}
/* Paperback section only: the index rail matches the bento's width (the Ebooksh rail keeps max-width 720) */
[data-section="paperback"] .index-rail{max-width:none}
/* Phones: 2 columns, big tile a full-width square (nothing shares its rows, so it needs its own height) */
@media (max-width:900px){ .cover-bento{grid-template-columns:repeat(2,1fr)} .cbt-big{aspect-ratio:1/1} }
/* Closing: larger headline (height-bounded on desktop), two doors, four shelf covers (lazy: far below the fold, with
   width/height so they reserve their square before they load), an About line. */
.closing-b .headline{font-size:clamp(40px, min(5.2vw, 9vh), 104px); line-height:.96; max-width:none}
.closing-b .closing-sub{margin-top:22px; font-size:clamp(22px, 1.9vw, 32px); color:var(--ink-2); font-weight:400; max-width:none}
.closing-b .ctas{margin-top:34px}
.closing-shelf{margin-top:clamp(24px, 5vh, 56px); max-width:640px}
/* Desktop: the row's width is bounded by the viewport's height too, so the centred closing still fits a ~650px screen
   with the About line (full 640px from ~915px tall up). */
@media (min-width:901px){ .closing-shelf{max-width:min(640px, 70vh)} }
.closing-shelf-row{display:grid; grid-template-columns:repeat(4, 1fr); gap:12px}
.closing-shelf-row a{display:block; aspect-ratio:1; background:var(--ink); border-radius:3px; overflow:hidden}
.closing-shelf-row img{width:100%; height:100%; object-fit:contain; display:block}
@media (hover:hover) and (prefers-reduced-motion:no-preference){ .closing-shelf-row a{transition:transform .25s ease-out} .closing-shelf-row a:hover{transform:translateY(-3px)} }
.closing-about{display:flex; gap:16px; align-items:baseline; max-width:52ch; margin:clamp(20px, 4vh, 48px) 0 0; padding-top:16px; border-top:1px solid var(--line); font-size:14px; line-height:1.55; color:var(--ink-2)}
.closing-about .mono{flex:none; text-transform:uppercase}
@media (max-width:900px){
  .closing-b .headline{font-size:clamp(40px, 11vw, 60px)}
  .closing-b .closing-sub{font-size:22px}
  .closing-shelf-row{gap:8px}
  .closing-about{margin-top:32px}
}
