/* Bound book tile (.db-book) and the cover hinge-open (.db-cover-open).
   Ported from the app shell (pipeline-lab/books/build_app.py: .bind, .spine, .spl, .orn, .lockp,
   .protag, .like, and the .portal book-open). ONE binding markup serves the tile, the book card and
   the open animation, so the three can never drift. Markup is built by js/components/shelf.js
   (DB.book.render / DB.book.bindingHTML); the open is driven by js/components/book-card.js. */

/* ---------- the tile ---------- */
.db-book{--db-leather:var(--db-leather-navy);position:relative;display:block;min-width:0;
  -webkit-tap-highlight-color:transparent;transition:transform var(--m-dur-fast) var(--m-ease-spring)}
/* a second, deeper shadow that fades in on hover: opacity only, the two-layer resting shadow never animates */
.db-book::before{content:"";position:absolute;inset:4% 2% 0 2%;border-radius:calc(var(--db-r-sm) / 4) var(--db-r-sm) var(--db-r-sm) calc(var(--db-r-sm) / 4);
  box-shadow:0 22px 34px rgba(4,6,20,.55),0 6px 12px rgba(4,6,20,.35);opacity:0;pointer-events:none;
  transition:opacity var(--m-dur) var(--m-ease)}
@media (hover:hover) and (pointer:fine){
  .db-book:hover{transform:translateY(-4px)}
  .db-book:hover::before{opacity:1}
}
.db-book.is-pressed,.db-book:has(.db-book__open:active){transform:scale(.95)}

/* ---------- the binding (tile, card, open animation) ---------- */
.db-book__bind{position:relative;display:block;aspect-ratio:16/10;container-type:inline-size;
  border-radius:calc(var(--db-r-sm) / 4) var(--db-r-sm) var(--db-r-sm) calc(var(--db-r-sm) / 4);
  background:var(--db-leather);overflow:hidden;isolation:isolate;
  box-shadow:0 12px 20px rgba(0,0,0,.5),0 2px 4px rgba(0,0,0,.4),inset 0 0 0 1px rgba(0,0,0,.35)}
/* leather grain, pressed into the colour */
.db-book__bind::before{content:"";position:absolute;inset:0;border-radius:inherit;z-index:1;pointer-events:none;
  background:url("../../assets/textures/leather-grain.png") 0 0/96px;opacity:.26;mix-blend-mode:overlay}
/* a soft top-light across the leather so it reads as a surface, not a flat fill */
.db-book__bind::after{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(160deg,rgba(255,255,255,.12),rgba(255,255,255,0) 38%,rgba(0,0,0,0) 62%,rgba(0,0,0,.22))}
.db-book__art{position:absolute;left:14.5%;top:9.5%;width:78.5%;height:81%;z-index:2;max-width:none;
  border-radius:calc(var(--db-r-sm) / 6);object-fit:cover;background:rgba(4,6,20,.6);
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.45)}
.db-book__art-shade{position:absolute;inset:9.5% 7% 9.5% 14.5%;z-index:2;pointer-events:none;border-radius:calc(var(--db-r-sm) / 6);
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.45),inset 0 0 10px rgba(0,0,0,.3)}
/* banded spine on the left: shading plus four gilt raised bands */
.db-book__spine{position:absolute;left:0;top:0;bottom:0;width:11%;z-index:3;pointer-events:none;
  border-radius:calc(var(--db-r-sm) / 4) 0 0 calc(var(--db-r-sm) / 4);
  background:linear-gradient(90deg,rgba(0,0,0,.6),rgba(0,0,0,.28) 45%,rgba(255,255,255,.14) 75%,rgba(0,0,0,.25))}
.db-book__spine::before{content:"";position:absolute;inset:0;
  background:repeating-linear-gradient(180deg,transparent 0 16%,rgba(255,240,180,.55) 16% 16.8%,rgba(0,0,0,.45) 16.8% 18.6%,rgba(255,255,255,.12) 18.6% 19.4%,transparent 19.4% 20%)}
/* cream page edges on the right */
.db-book__pages{position:absolute;right:0;top:3%;bottom:3%;width:2.6%;z-index:2;pointer-events:none;
  border-radius:0 calc(var(--db-r-sm) / 2.4) calc(var(--db-r-sm) / 2.4) 0;
  background:repeating-linear-gradient(180deg,var(--db-page) 0 2px,var(--db-page-shadow) 2px 3px);
  box-shadow:inset 1px 0 0 rgba(0,0,0,.25)}
/* gilt double rule + four corner fleurons (the SVG is 160x100, the tile exactly 16:10) */
.db-book__orn{position:absolute;inset:0;width:100%;height:100%;z-index:4;pointer-events:none;max-width:none}
/* the age: a gilt label on the spine, digits upright so it reads without tilting your head */
.db-book__age{position:absolute;left:1px;top:50%;z-index:7;width:calc(11% - 1px);max-height:78%;overflow:hidden;
  transform:translateY(-50%);display:flex;flex-direction:column;align-items:center;justify-content:center;
  padding:.4em 0 .32em;pointer-events:none;font-size:clamp(11px,6.4cqw,26px);
  background:linear-gradient(180deg,rgba(0,0,0,.55),rgba(0,0,0,.8) 35%,rgba(0,0,0,.55));
  border-block:1.5px solid var(--db-spine-rule);
  box-shadow:0 0 0 1px rgba(0,0,0,.5),inset 0 0 0 .5px rgba(255,235,170,.25)}
.db-book__age i{display:block;font-style:normal;font-family:var(--db-font);font-weight:700;font-size:1em;line-height:1.05;
  color:var(--db-spine-gold);text-shadow:0 1px 0 rgba(0,0,0,.7)}
.db-book__age i.is-dash{font-size:.8em;line-height:.8;opacity:.9}

/* ---------- states ---------- */
/* locked: dimmed art, a big gold padlock plate, a PRO tag. A status, never a button. */
.db-book.is-locked .db-book__art{filter:brightness(.6) saturate(.65)}
.db-book__lock{position:absolute;left:50%;top:50%;z-index:8;width:46px;height:46px;margin:-23px 0 0 -23px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;pointer-events:none;
  background:linear-gradient(160deg,var(--db-gold-pale),var(--db-gold) 55%,var(--db-gold-2));
  box-shadow:0 6px 16px rgba(0,0,0,.55),inset 0 1px 0 rgba(255,255,255,.6),0 0 0 3px rgba(255,206,92,.25)}
.db-book__lock svg{width:25px;height:25px;fill:none;stroke:var(--db-on-gold);stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
.db-book__tag{position:absolute;top:5%;right:6%;z-index:8;padding:.18em .7em .1em;border-radius:var(--db-r-pill);pointer-events:none;
  font-family:var(--db-font);font-size:.62rem;font-weight:800;letter-spacing:.1em;line-height:1.3;
  background:linear-gradient(135deg,var(--db-gold),var(--db-gold-2));color:var(--db-on-gold);box-shadow:0 2px 6px rgba(0,0,0,.4)}
.db-book__tag--free{background:var(--db-free);color:rgba(0,0,0,.78)}
/* "no" wiggle when a locked book is tapped (transform only) */
@keyframes db-book-nope{0%,100%{transform:rotate(0)}20%{transform:rotate(-6deg)}40%{transform:rotate(6deg)}60%{transform:rotate(-3deg)}80%{transform:rotate(3deg)}}
@keyframes db-book-lockpulse{0%,100%{transform:scale(1)}40%{transform:scale(1.22)}}
.db-book.is-nope .db-book__bind{animation:db-book-nope var(--m-dur-slow) ease-in-out}
.db-book.is-nope .db-book__lock{animation:db-book-lockpulse var(--m-dur-slow) ease-out}

/* ---------- controls ---------- */
/* the whole cover is one real button; the heart is a sibling so buttons never nest */
.db-book__open{position:absolute;inset:0;z-index:9;width:100%;aspect-ratio:16/10;height:auto;margin:0;padding:0;border:0;
  background:transparent;cursor:pointer;border-radius:calc(var(--db-r-sm) / 4) var(--db-r-sm) var(--db-r-sm) calc(var(--db-r-sm) / 4)}
.db-book__open:focus-visible{outline:3px solid var(--db-focus);outline-offset:3px}
.db-book__like{position:absolute;right:5px;/* bottom-right: every cover's painted title runs across the top */z-index:10;width:44px;height:44px;padding:0;border:0;border-radius:50%;cursor:pointer;
  bottom:5px;
  display:flex;align-items:center;justify-content:center;background:rgba(10,12,28,.5);
  -webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px);transition:transform var(--m-dur-fast) var(--m-ease),background-color var(--m-dur-fast) linear}
.db-book__like svg{width:21px;height:21px;fill:none;stroke:var(--db-ink);stroke-width:2;overflow:visible}
.db-book__like:hover{background:rgba(10,12,28,.7)}
.db-book__like:active{transform:scale(.82)}
.db-book__like[aria-pressed="true"] svg{fill:var(--db-gold);stroke:var(--db-gold)}
@keyframes db-book-heart{0%{transform:scale(1)}35%{transform:scale(1.34)}100%{transform:scale(1)}}
.db-book__like.is-pop svg{animation:db-book-heart var(--m-dur) var(--m-ease-spring)}

/* sizes: the book card and the open animation use the same binding, bigger */
.db-book__bind--lg{box-shadow:0 26px 60px rgba(0,0,0,.6),0 2px 4px rgba(0,0,0,.4),inset 0 0 0 1px rgba(0,0,0,.35)}

/* placeholder while the cover loads */
.db-book__bind.is-ph .db-book__art{background:linear-gradient(135deg,var(--db-card-2),var(--db-card))}

@media (prefers-reduced-motion:reduce){
  .db-book,.db-book::before,.db-book__like{transition:none}
  .db-book.is-nope .db-book__bind,.db-book.is-nope .db-book__lock,.db-book__like.is-pop svg{animation:none}
  .db-book:hover{transform:none}
}

/* =====================================================================
   COVER HINGE-OPEN (.db-cover-open): the Read moment.
   The bound book lifts, its front cover hinges open about the spine (rotateY on the left edge, an
   endpaper on the back face, a shadow sweeping off page 1), then the page settles to fill the stage.
   Transform and opacity only. Reduce Motion: a straight cut to the open page.
   ===================================================================== */
.db-cover-open{position:relative;display:block;width:100%;aspect-ratio:16/10;overflow:hidden;isolation:isolate;
  border-radius:var(--db-r-lg);background:radial-gradient(90% 80% at 50% 40%,var(--db-night-top),var(--db-night-bottom) 75%);
  box-shadow:var(--db-shadow-2);container-type:inline-size}
.db-cover-open__table{position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(60% 40% at 50% 72%,rgba(255,206,92,.10),rgba(255,206,92,0) 70%)}
/* the lift layer: the book's layout box; JS moves it with transform only */
.db-cover-open__book{position:absolute;left:30%;top:calc(50% - 12.5cqw);width:40%;cursor:pointer;aspect-ratio:16/10;
  transform-origin:50% 50%;will-change:transform}
.db-cover-open__inner{position:absolute;inset:0;perspective:1800px;perspective-origin:38% 50%}
/* page 1, under the cover */
.db-cover-open__page{position:absolute;inset:0;overflow:hidden;background:var(--db-page) center/cover no-repeat;
  border-radius:calc(var(--db-r-sm) / 4) var(--db-r-sm) var(--db-r-sm) calc(var(--db-r-sm) / 4);
  box-shadow:0 12px 20px rgba(0,0,0,.5),0 2px 4px rgba(0,0,0,.4)}
.db-cover-open__stack{position:absolute;right:0;top:0;bottom:0;width:.9%;background:repeating-linear-gradient(180deg,var(--db-page) 0 2px,var(--db-page-shadow) 2px 3px)}
.db-cover-open__stack2{position:absolute;left:0;right:0;bottom:0;height:.9%;background:repeating-linear-gradient(90deg,var(--db-page) 0 2px,var(--db-page-shadow) 2px 3px)}
.db-cover-open__gutter{position:absolute;left:0;top:0;bottom:0;width:7%;pointer-events:none;background:linear-gradient(90deg,rgba(0,0,0,.42),rgba(0,0,0,.12) 55%,transparent)}
.db-cover-open__shade{position:absolute;inset:0;pointer-events:none;opacity:.6;
  background:linear-gradient(90deg,rgba(0,0,0,.72) 0%,rgba(0,0,0,.45) 35%,rgba(0,0,0,.15) 70%,rgba(0,0,0,0))}
.db-cover-open__cap{position:absolute;left:0;right:0;bottom:0;z-index:3;margin:0;opacity:0;pointer-events:none;
  padding:clamp(22px,8cqw,72px) clamp(20px,7cqw,86px) clamp(18px,4cqw,44px);text-align:center;font-family:var(--db-font);font-weight:600;line-height:1.34;
  font-size:clamp(12px,2.05cqw,24px);color:var(--db-caption);text-wrap:pretty;
  background:linear-gradient(to top,rgba(6,9,16,.84) 0%,rgba(6,9,16,.52) 40%,rgba(6,9,16,.18) 70%,rgba(6,9,16,0) 100%);
  text-shadow:0 2px 14px rgba(0,0,0,.6),0 1px 3px rgba(0,0,0,.55)}
/* the front cover: its binding on the front face, an endpaper on the back */
.db-cover-open__flip{position:absolute;inset:0;transform-origin:left center;transform-style:preserve-3d;will-change:transform}
.db-cover-open__face,.db-cover-open__end{position:absolute;inset:0;backface-visibility:hidden;-webkit-backface-visibility:hidden;
  border-radius:calc(var(--db-r-sm) / 4) var(--db-r-sm) var(--db-r-sm) calc(var(--db-r-sm) / 4)}
.db-cover-open__face.db-book__bind{aspect-ratio:auto}
.db-cover-open__end{transform:rotateY(180deg);
  background:radial-gradient(120% 100% at 50% 50%,rgba(255,255,255,.4),rgba(120,90,40,.18)),var(--db-page);
  box-shadow:inset 0 0 0 1px rgba(90,60,20,.25),inset 0 0 40px rgba(90,60,20,.18)}
.db-cover-open__end::after{content:"";position:absolute;inset:5%;border:1px solid rgba(120,90,40,.35);border-radius:calc(var(--db-r-sm) / 6)}
/* the toggle: a small gold pill under the book */
.db-cover-open__toggle{position:absolute;left:50%;bottom:clamp(10px,4%,24px);z-index:5;transform:translateX(-50%);
  transition:opacity var(--m-dur) var(--m-ease),transform var(--m-dur) var(--m-ease)}
.db-cover-open.is-busy .db-cover-open__toggle{opacity:0;pointer-events:none}
.db-cover-open.is-open .db-cover-open__toggle{--h:44px;padding:0 1.1rem;font-size:.95rem;
  background:rgba(8,9,20,.55);color:var(--db-ink);box-shadow:0 0 0 1px rgba(255,255,255,.2) inset;
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);top:clamp(10px,4%,24px);bottom:auto}
/* when it is used as the full-screen Read overlay (book card), the stage is the viewport */
.db-cover-open--portal{position:fixed;inset:0;z-index:5;width:auto;aspect-ratio:auto;border-radius:0;background:none;box-shadow:none;pointer-events:none}
.db-cover-open--portal .db-cover-open__book{left:0;top:0;cursor:default}
