/* Paper, quiet reading controls, and a movable forest magnifier. */
.bound-reader{max-width:1400px;margin:auto;padding:30px 7% 40px}
/* The hint sits right under the stump: the photograph carries its own 20px of
   empty ground below the wood, and that is the whole of the gap. */
.book-viewport{max-width:1120px;margin:0 auto;padding:42px 0 0;overflow:visible;overscroll-behavior-x:contain;scrollbar-width:none}
.book-viewport::-webkit-scrollbar{display:none}
.book-viewport:focus-visible{outline:2px solid #8aa48c;outline-offset:5px;border-radius:8px}
/* --gutter is where the spine really is, as a fraction of the book's width.
   Everything that has to meet at the spine reads it: where the two pages are
   cut apart, where a leaf is hinged, which half a click belongs to. */
/* --turn-depth is the camera, and a turn moves it: paper lifted off the page is
   nearer the eye, so a close camera paints it bigger than the book it belongs
   to. It draws back as the paper rises, and stands at --desk-depth otherwise. */
.reading-desk{--gutter:.5;--desk-depth:2200px;position:relative;width:var(--book-size,100%);margin:0 auto;
  perspective:var(--turn-depth,var(--desk-depth));perspective-origin:50% 45%;isolation:isolate}
.bound-book{position:relative;width:100%;aspect-ratio:2000/804;transform-style:preserve-3d;user-select:none;-webkit-user-select:none;touch-action:pan-y pinch-zoom;--turn-shadow:0}
.bound-pages{position:absolute;inset:0;display:grid;grid-template-columns:calc(var(--gutter,.5) * 100%) 1fr;transform-style:preserve-3d}
.bound-page{position:relative;min-width:0;overflow:hidden;background:#fffdf5;border-radius:3px 8px 8px 3px;box-shadow:0 2px 0 #f8f1de,0 5px 0 #d8ccb2,0 7px 0 #fff9e8,0 10px 0 #a99e83,0 13px 0 #627961,0 30px 35px -15px #243e3a6b}
.bound-page:first-child{border-radius:8px 3px 3px 8px}
/* Each page carries the whole spread and shows its own share of it, so the two
   halves stay one photograph however the spine divides them. */
.bound-page img{display:block;width:calc(100% / var(--gutter,.5));max-width:none;height:100%;object-fit:fill;pointer-events:none}
.bound-page.right img{width:calc(100% / (1 - var(--gutter,.5)));margin-left:calc(-100% * var(--gutter,.5) / (1 - var(--gutter,.5)))}
.bound-page:after{content:'';position:absolute;inset:0;pointer-events:none;background:linear-gradient(90deg,#36271736,transparent 8%,#fffdf500 85%,#57472c0b)}
.bound-page:first-child:after{background:linear-gradient(90deg,#57472c0b,#fffdf500 15%,transparent 90%,#36271742)}
/* The shadow a turn casts into the gutter. It is masked with the page's own
   art, because the art is a cut-out of a real book: an unmasked overlay would
   lay a translucent black rectangle over the photographed desk. */
.bound-page:before{content:'';position:absolute;inset:0;z-index:5;pointer-events:none;opacity:var(--turn-shadow,0);
  background:linear-gradient(90deg,#392b1d00 74%,#392b1d1a 88%,#392b1d80);
  -webkit-mask-image:var(--page-mask,none);mask-image:var(--page-mask,none);
  -webkit-mask-size:calc(100% / var(--gutter,.5)) 100%;mask-size:calc(100% / var(--gutter,.5)) 100%;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}
.bound-page.right:before{background:linear-gradient(90deg,#392b1d80,#392b1d1a 12%,#392b1d00 26%);
  -webkit-mask-size:calc(100% / (1 - var(--gutter,.5))) 100%;mask-size:calc(100% / (1 - var(--gutter,.5))) 100%;
  -webkit-mask-position:100% 0;mask-position:100% 0}
.bound-book:before{content:'';position:absolute;top:1%;bottom:-10px;left:calc(var(--gutter,.5) * 100%);width:3%;transform:translateX(-50%);z-index:4;pointer-events:none;background:linear-gradient(90deg,transparent,#48351a2e 42%,#382a1a57 50%,#fffefa66 55%,transparent)}
.bound-book .paper-curl{
  position:absolute;top:0;width:0;height:100%;z-index:30;
  transform-style:preserve-3d;pointer-events:none;
}
/* --grow carries the leaf across the difference between the two halves: the
   page it leaves and the page it lands on are not the same width, because the
   book was photographed a little off the spine. */
.bound-book .paper-curl.next{left:calc(var(--gutter,.5) * 100%);right:auto;transform-origin:0 50%;
  transform:rotateY(calc(-1 * var(--tt,0deg))) scaleX(calc(var(--grow,1) * var(--fit,1)))}
.bound-book .paper-curl.prev{left:auto;right:calc(100% - var(--gutter,.5) * 100%);transform-origin:100% 50%;
  transform:rotateY(var(--tt,0deg)) scaleX(calc(var(--grow,1) * var(--fit,1)))}
/* will-change:auto is deliberate. Promoted to its own layer, a strip is painted
   from a texture rasterised for the widest the leaf ever gets, and lands about
   1% larger than its own box -- so the art on a turning leaf never quite lines
   up with the page beneath it, and snaps to size when the page takes over. */
.bound-book .paper-strip{position:absolute;top:0;height:100%;width:var(--strip-width);transform-style:preserve-3d;will-change:auto}
.bound-book .paper-curl.next .paper-strip{transform-origin:0 50%}
.bound-book .paper-curl.prev .paper-strip{transform-origin:100% 50%}
.bound-book .paper-curl.next>.paper-strip{left:0;right:auto;transform:none}
.bound-book .paper-curl.prev>.paper-strip{right:0;left:auto;transform:none}
.bound-book .paper-curl.next .paper-strip .paper-strip{left:100%;right:auto;transform:rotateY(var(--td,0deg))}
.bound-book .paper-curl.prev .paper-strip .paper-strip{right:100%;left:auto;transform:rotateY(calc(-1 * var(--td,0deg)))}
/* Faces overrun their strip on both sides, so hinges never split open. */
/* No paper colour behind the art: the art itself is the paper, cut out of a
   photograph, so a fill would show as a white sheet stuck to the leaf. */
.bound-book .paper-face{inset:0 -1px;background-color:transparent;-webkit-backface-visibility:hidden;backface-visibility:hidden}
.bound-book .paper-face:after{content:none;display:none}
/* Light and shade run edge to edge across every hinge, so the curve reads as
   one sheet instead of a stack of differently lit slats. */
.bound-book .paper-shade,.bound-book .paper-glint{position:absolute;inset:0;pointer-events:none}
.bound-book .paper-curl.next .paper-face.front .paper-shade,
.bound-book .paper-curl.prev .paper-face.back .paper-shade{
  background:linear-gradient(90deg,rgba(58,43,20,var(--a1,0)),rgba(58,43,20,var(--a2,0)));
}
.bound-book .paper-curl.next .paper-face.back .paper-shade,
.bound-book .paper-curl.prev .paper-face.front .paper-shade{
  background:linear-gradient(90deg,rgba(58,43,20,var(--a2,0)),rgba(58,43,20,var(--a1,0)));
}
.bound-book .paper-curl.next .paper-face.front .paper-glint,
.bound-book .paper-curl.prev .paper-face.back .paper-glint{
  background:linear-gradient(90deg,rgba(255,250,240,calc(var(--turn-glint,0)*var(--g1,0))),rgba(255,250,240,calc(var(--turn-glint,0)*var(--g2,0))));
}
.bound-book .paper-curl.next .paper-face.back .paper-glint,
.bound-book .paper-curl.prev .paper-face.front .paper-glint{
  background:linear-gradient(90deg,rgba(255,250,240,calc(var(--turn-glint,0)*var(--g2,0))),rgba(255,250,240,calc(var(--turn-glint,0)*var(--g1,0))));
}
.page-edge{position:absolute;top:0;bottom:0;width:50%;border:0;padding:0;margin:0;appearance:none;-webkit-appearance:none;background:transparent;box-shadow:none;color:transparent;z-index:20;cursor:grab;touch-action:pan-y pinch-zoom;opacity:0}
.page-edge.left{left:0}.page-edge.right{right:0}.page-edge:active{cursor:grabbing}.page-edge:disabled{visibility:hidden}.page-edge:focus-visible{opacity:1;outline:2px solid #ae925f;outline-offset:6px;border-radius:4px;background:transparent}
.bound-book[data-turning=true] .page-edge{cursor:grabbing}
.loupe-layer{position:fixed;inset:0;overflow:clip;contain:strict;z-index:1000;pointer-events:none}
.book-loupe{position:absolute;left:0;top:0;width:var(--skin-width);aspect-ratio:1;pointer-events:none}
.loupe-skin{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;filter:drop-shadow(2px 7px 5px #1b34272d);mask-image:radial-gradient(circle calc(var(--lens-size)*.5) at 39.0715% 36.8576%,transparent calc(100% - .5px),#000 100%)}
.loupe-window{position:absolute;left:39.0715%;top:36.8576%;width:calc(var(--lens-size) + 2px);height:calc(var(--lens-size) + 2px);transform:translate(-50%,-50%);border-radius:50%;overflow:hidden;isolation:isolate;pointer-events:none;background:var(--mint)}
.loupe-content{position:absolute;left:50%;top:50%;width:var(--loupe-content-size,100%);height:var(--loupe-content-size,100%);transform:translate(-50%,-50%);pointer-events:none}
.loupe-scene{position:absolute;left:0;top:0;width:100%;height:100%;transform-origin:0 0;pointer-events:none;user-select:none;background:var(--mint)}
.loupe-glass{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;display:block}
.loupe-ring{position:absolute;left:39.0715%;top:36.8576%;width:calc(var(--lens-size)*1.08);aspect-ratio:1;transform:translate(-50%,-50%);border-radius:50%;padding:0;border:0;background:transparent;pointer-events:auto;cursor:grab;touch-action:none}
.loupe-ring:focus,.loupe-ring:focus-visible{outline:none}
.book-loupe[data-focus=keyboard] .loupe-ring:focus{outline:2px solid #8f7343;outline-offset:2px}
.loupe-handle{position:absolute;left:61%;top:57%;width:43%;height:16%;transform:rotate(45deg);transform-origin:0 50%;pointer-events:auto;cursor:grab;touch-action:none}
.book-loupe[data-held=true] .loupe-ring,.book-loupe[data-held=true] .loupe-handle{cursor:grabbing}
/* Growing and shrinking the glass, from the handle. The row rides the wood's
   own diagonal and gathers at the top of it, just past the ferrule, so that
   most of the handle is still there to grip. The glyphs stay upright, and only
   the menu button shows until it is asked to unfold the rest. */
.loupe-size{position:absolute;left:68.25%;top:61.45%;width:30%;height:8%;transform:rotate(45deg);transform-origin:0 50%;
  display:flex;align-items:center;gap:calc(var(--lens-size) * .022);pointer-events:none}
.loupe-size button{pointer-events:auto;flex:0 0 auto;display:grid;place-items:center;padding:0;border:0;border-radius:50%;
  width:clamp(16px,calc(var(--lens-size) * .077),27px);aspect-ratio:1;transform:rotate(-45deg);cursor:pointer;
  background:#fbf6ea33;color:#f6f0e0;box-shadow:inset 0 0 0 1px #f6efdf4d;transition:background .12s,color .12s}
.loupe-size button[data-lens]{transition:opacity .16s,transform .16s,visibility .16s,background .12s,color .12s}
.loupe-size button[data-lens=out]{margin-left:calc(var(--lens-size) * .028)}
.loupe-size[data-open=false] button[data-lens]{opacity:0;visibility:hidden;pointer-events:none;transform:rotate(-45deg) scale(.5)}
.loupe-size .mark-shut,.loupe-size[data-open=true] .mark-menu{display:none}
.loupe-size[data-open=true] .mark-shut{display:initial}
/* The menu button is the one that is always there, so it is drawn in ink. */
.loupe-size .loupe-menu{color:#161616;box-shadow:inset 0 0 0 1px #161616b3}
.loupe-size .loupe-menu svg{filter:none;width:74%;height:74%;stroke-width:1.9}
.loupe-size .loupe-menu:hover{color:#000}
.loupe-size button svg{width:62%;height:62%;fill:none;stroke:currentColor;stroke-width:2.8;stroke-linecap:round;stroke-linejoin:round;
  filter:drop-shadow(0 1px 1px #16241a73)}
.loupe-size button:hover{background:#fbf6ea80;color:#fffdf5}
.loupe-size button:active{background:#fbf6ea99}
.loupe-size button:disabled{opacity:.4;cursor:default}
.loupe-size button:focus{outline:none}
.book-loupe[data-focus=keyboard] .loupe-size button:focus{outline:2px solid #8f7343;outline-offset:2px}
.bound-reader .reader-controls{margin:0 auto 22px}.bound-reader .page-meter{min-width:136px}.bound-reader .page-indicator{font-size:13px;white-space:nowrap}
.desk-hint{text-align:center;margin:0;font-size:13px;color:#6f806d;line-height:1.8}
@media(max-width:700px){.bound-reader{padding:22px 5% 30px}.book-viewport{padding:30px 0 0;margin-bottom:0}.bound-page{box-shadow:0 2px 0 #f8f1de,0 4px 0 #d8ccb2,0 6px 0 #a99e83,0 8px 0 #627961,0 22px 25px -12px #243e3a6b}.desk-hint{font-size:12px}.reading-heading h1{font-size:30px}.bound-reader .reader-controls{gap:8px}.bound-reader .reader-controls button{min-width:70px;padding:10px;gap:6px}.bound-reader .page-meter{min-width:124px}.bound-reader .page-indicator{font-size:12px}}
