/* Moving between pages with the same book the home page opens. The camera zooms out until the page you're on is
   the right-hand page of that book — same size and proportions, at the same place — with the page's Monet as a
   plate on the facing page. The page turns over the spine: its back carries the next page's painting, which lands
   as the new plate, revealing the next page beneath; then the camera zooms into it. Going back, the plate on the
   left turns back over and brings the earlier page down onto the right. Going home, the page is lowered away.

   pageturn.js measures the book (--bk-*), picks the direction (forward / back / home) and builds the sheets:
     bk-verso   the facing page, a plate                       bk-recto   the right-hand page's paper
     bk-leaf    the paper of the page that turns               bk-back    the back of that leaf, a plate (mirrored)
   Book space: spine at --bk-sx, top at --bk-ty, pages --bk-pw × --bk-ph; a page's screenshot sits at its top,
   scaled by --bk-k = page width / window width. The camera zoomed in maps the right page onto the window.
   Timeline: 0–26% zoom out · 26–74% the turn (front to 50%, back after) · 74–100% zoom in. */

@view-transition { navigation: auto; }

:root {
  --turn-time: 1.9s;
  --zoom-ease: cubic-bezier(.6, .02, .22, 1);
  --turn-in: cubic-bezier(.5, 0, .75, .55);         /* the turn, split across two faces at the vertical: */
  --turn-out: cubic-bezier(.25, .45, .5, 1);        /* ease in, then ease out at the same speed */
  --bk-cut: inset(0 0 max(0px, 100% - var(--bk-ph) * var(--bk-ik)) 0);   /* a phone window is taller than a page: in the book its screenshot stops at the page's foot */
}

/* the sheets exist only while a page is turning */
.bk-sheet {
  position: fixed; left: 0; top: 0; z-index: -1; pointer-events: none;
  box-sizing: border-box;
  background: #f9f1e2;
  font: italic 13px/1 "Lora", Georgia, serif; color: #8c95a1;
}
.bk-sheet .bk-art {                         /* a plate: the page's painting, tipped in */
  position: absolute; left: 50%; top: 44%; width: 74%; translate: -50% -50%;
  aspect-ratio: var(--ratio, 4 / 3);
  background: rgb(30 33 37 / .06) center / cover no-repeat;
  box-shadow: 0 0 0 1px rgb(30 33 37 / .08), 0 1px 2px rgb(30 33 37 / .08), 0 10px 22px -10px rgb(30 33 37 / .3);
}
.bk-sheet .bk-fleuron { position: absolute; left: 0; right: 0; top: 44%; translate: 0 -50%; text-align: center; font-size: 28px; color: #b9b2a3; }
.bk-verso { background: linear-gradient(to left, rgb(70 48 26 / .18), transparent 7%) #f9f1e2;          /* gutter on the right, */
  box-shadow: -1px 1px 0 #ebe4d5, -2px 2px 0 #dcd3c0, -3px 3px 0 #e7e0cf, -4px 4px 0 #d4cab5; }         /* page edges as on the home book */
.bk-recto { background: #f9f1e2;                    /* plain, so the page's screenshot sits on it without a seam */
  box-shadow: 1px 1px 0 #ebe4d5, 2px 2px 0 #dcd3c0, 3px 3px 0 #e7e0cf, 4px 4px 0 #d4cab5, 5px 5px 0 #c4b9a2; }
.bk-leaf { background: #f9f1e2; }
.bk-back { overflow: hidden; }
.bk-back .bk-face { position: absolute; inset: 0; transform: scaleX(-1);                                  /* seen from behind, it reads right */
  background: linear-gradient(to left, rgb(70 48 26 / .18), transparent 7%); }

/* the white page the book lies on, as on the home page, with the open book's shadow */
:root:active-view-transition-type(forward, back)::view-transition {
  background:
    radial-gradient(calc(var(--bk-pw) * 1.25) calc(var(--bk-ph) * .62) at var(--bk-sx) calc(var(--bk-ty) + var(--bk-ph) * .56),
      rgb(30 33 37 / .2), transparent 72%),
    #fcf9f3;
  perspective: 3000px;
  perspective-origin: var(--bk-sx) calc(var(--bk-ty) + var(--bk-ph) / 2);
}
:root:active-view-transition-type(home)::view-transition { background: #fcf9f3; }
:root:active-view-transition-type(forward, back)::view-transition-image-pair(root) {
  perspective: 3000px;
  perspective-origin: var(--bk-sx) calc(var(--bk-ty) + var(--bk-ph) / 2);
}

:root:active-view-transition-type(forward, back)::view-transition-group(bk-verso),
:root:active-view-transition-type(forward, back)::view-transition-group(bk-recto) { z-index: 0; }
:root:active-view-transition-type(forward, back)::view-transition-group(bk-leaf) { z-index: 1; }
:root:active-view-transition-type(forward, back)::view-transition-group(root) { z-index: 2; }
:root:active-view-transition-type(forward, back)::view-transition-group(bk-back) { z-index: 3; }
/* the sheets were cut on the page being left; if the window has changed height since (a phone's toolbar), draw them at this book's size */
:root:active-view-transition-type(forward, back)::view-transition-group(bk-verso),
:root:active-view-transition-type(forward, back)::view-transition-group(bk-recto),
:root:active-view-transition-type(forward, back)::view-transition-group(bk-leaf),
:root:active-view-transition-type(forward, back)::view-transition-group(bk-back) { width: var(--bk-pw); height: var(--bk-ph); }
:root:active-view-transition-type(forward, back)::view-transition-old(*) { animation: none; }

:root:active-view-transition-type(forward, back)::view-transition-old(root),
:root:active-view-transition-type(forward, back)::view-transition-new(root),
:root:active-view-transition-type(forward, back)::view-transition-group(bk-verso),
:root:active-view-transition-type(forward, back)::view-transition-group(bk-recto),
:root:active-view-transition-type(forward, back)::view-transition-group(bk-leaf),
:root:active-view-transition-type(forward, back)::view-transition-group(bk-back) {
  transform-origin: 0 0;
  animation-duration: var(--turn-time);
  animation-fill-mode: both;
}
:root:active-view-transition-type(forward, back)::view-transition-old(root),
:root:active-view-transition-type(forward, back)::view-transition-new(root) { backface-visibility: hidden; mix-blend-mode: normal; }
:root:active-view-transition-type(forward, back)::view-transition-group(bk-verso) { animation-name: bk-left-page; }
:root:active-view-transition-type(forward, back)::view-transition-group(bk-recto) { animation-name: bk-right-page; }

/* forward: the page you leave turns over; the next one waits beneath */
:root:active-view-transition-type(forward)::view-transition-old(root) { z-index: 1; animation-name: bk-shot-turns-away; }
:root:active-view-transition-type(forward)::view-transition-new(root) { animation-name: bk-shot-waits; }
:root:active-view-transition-type(forward)::view-transition-group(bk-leaf) { animation-name: bk-sheet-turns-away; }
:root:active-view-transition-type(forward)::view-transition-group(bk-back) { animation-name: bk-back-lands; }
/* back: the plate on the left turns back over and brings the earlier page down onto the right */
:root:active-view-transition-type(back)::view-transition-group(bk-back) { animation-name: bk-back-lifts; }
:root:active-view-transition-type(back)::view-transition-new(root) { z-index: 1; animation-name: bk-shot-turns-in; }
:root:active-view-transition-type(back)::view-transition-group(bk-leaf) { animation-name: bk-sheet-turns-in; }
:root:active-view-transition-type(back)::view-transition-old(root) { animation-name: bk-shot-covered; }

/* --- the pages' screenshots (window-sized; in the book they sit at the top of the right page, scaled by k) --- */
@keyframes bk-shot-turns-away {
  0%   { transform: translate(0px, 0px) scale(1) rotateY(0deg); clip-path: inset(0); filter: brightness(1); animation-timing-function: var(--zoom-ease); }
  26%  { transform: translate(var(--bk-sx), var(--bk-ty)) scale(var(--bk-k)) rotateY(0deg); clip-path: var(--bk-cut); filter: brightness(1); animation-timing-function: var(--turn-in); }
  50%  { transform: translate(var(--bk-sx), var(--bk-ty)) scale(var(--bk-k)) rotateY(-90deg); clip-path: var(--bk-cut); filter: brightness(.82); opacity: 1; }
  50.1%, 100% { transform: translate(var(--bk-sx), var(--bk-ty)) scale(var(--bk-k)) rotateY(-90deg); clip-path: var(--bk-cut); filter: brightness(.82); opacity: 0; }
}
@keyframes bk-shot-waits {
  0%   { transform: translate(0px, 0px) scale(1) rotateY(0deg); clip-path: inset(0); filter: brightness(.9); animation-timing-function: var(--zoom-ease); }
  26%  { transform: translate(var(--bk-sx), var(--bk-ty)) scale(var(--bk-k)) rotateY(0deg); clip-path: var(--bk-cut); filter: brightness(.84); }
  74%  { transform: translate(var(--bk-sx), var(--bk-ty)) scale(var(--bk-k)) rotateY(0deg); clip-path: var(--bk-cut); filter: brightness(1); animation-timing-function: var(--zoom-ease); }
  100% { transform: translate(0px, 0px) scale(1) rotateY(0deg); clip-path: inset(0); filter: brightness(1); }
}
@keyframes bk-shot-turns-in {
  0%, 50% { transform: translate(var(--bk-sx), var(--bk-ty)) scale(var(--bk-k)) rotateY(-90deg); clip-path: var(--bk-cut); filter: brightness(.82); opacity: 0; }
  50.1%   { transform: translate(var(--bk-sx), var(--bk-ty)) scale(var(--bk-k)) rotateY(-89.8deg); clip-path: var(--bk-cut); filter: brightness(.82); opacity: 1; animation-timing-function: var(--turn-out); }
  74%     { transform: translate(var(--bk-sx), var(--bk-ty)) scale(var(--bk-k)) rotateY(0deg); clip-path: var(--bk-cut); filter: brightness(1); opacity: 1; animation-timing-function: var(--zoom-ease); }
  100%    { transform: translate(0px, 0px) scale(1) rotateY(0deg); clip-path: inset(0); filter: brightness(1); opacity: 1; }
}
@keyframes bk-shot-covered {
  0%   { transform: translate(0px, 0px) scale(1) rotateY(0deg); clip-path: inset(0); filter: brightness(1); animation-timing-function: var(--zoom-ease); }
  26%  { transform: translate(var(--bk-sx), var(--bk-ty)) scale(var(--bk-k)) rotateY(0deg); clip-path: var(--bk-cut); filter: brightness(1); }
  74%, 100% { transform: translate(var(--bk-sx), var(--bk-ty)) scale(var(--bk-k)) rotateY(0deg); clip-path: var(--bk-cut); filter: brightness(.84); }
}

/* --- the page-sized sheets (built at the window's top-left, so their own transform places them) --- */
@keyframes bk-left-page {
  0%   { transform: translate(calc(var(--bk-vw) * -1), 0px) scale(var(--bk-ik)) rotateY(0deg); animation-timing-function: var(--zoom-ease); }
  26%, 74% { transform: translate(var(--bk-vx), var(--bk-ty)) scale(1) rotateY(0deg); animation-timing-function: var(--zoom-ease); }
  100% { transform: translate(calc(var(--bk-vw) * -1), 0px) scale(var(--bk-ik)) rotateY(0deg); }
}
@keyframes bk-right-page {
  0%   { transform: translate(0px, 0px) scale(var(--bk-ik)) rotateY(0deg); animation-timing-function: var(--zoom-ease); }
  26%, 74% { transform: translate(var(--bk-sx), var(--bk-ty)) scale(1) rotateY(0deg); animation-timing-function: var(--zoom-ease); }
  100% { transform: translate(0px, 0px) scale(var(--bk-ik)) rotateY(0deg); }
}
@keyframes bk-sheet-turns-away {
  0%   { transform: translate(0px, 0px) scale(var(--bk-ik)) rotateY(0deg); filter: brightness(1); animation-timing-function: var(--zoom-ease); }
  26%  { transform: translate(var(--bk-sx), var(--bk-ty)) scale(1) rotateY(0deg); filter: brightness(1); animation-timing-function: var(--turn-in); }
  50%  { transform: translate(var(--bk-sx), var(--bk-ty)) scale(1) rotateY(-90deg); filter: brightness(.82); opacity: 1; }
  50.1%, 100% { transform: translate(var(--bk-sx), var(--bk-ty)) scale(1) rotateY(-90deg); filter: brightness(.82); opacity: 0; }
}
@keyframes bk-sheet-turns-in {
  0%, 50% { transform: translate(var(--bk-sx), var(--bk-ty)) scale(1) rotateY(-90deg); filter: brightness(.82); opacity: 0; }
  50.1%   { transform: translate(var(--bk-sx), var(--bk-ty)) scale(1) rotateY(-89.8deg); filter: brightness(.82); opacity: 1; animation-timing-function: var(--turn-out); }
  74%     { transform: translate(var(--bk-sx), var(--bk-ty)) scale(1) rotateY(0deg); filter: brightness(1); opacity: 1; animation-timing-function: var(--zoom-ease); }
  100%    { transform: translate(0px, 0px) scale(var(--bk-ik)) rotateY(0deg); filter: brightness(1); opacity: 1; }
}
@keyframes bk-back-lands {
  0%, 50% { transform: translate(var(--bk-sx), var(--bk-ty)) scale(1) rotateY(-90deg); filter: brightness(.82); opacity: 0; }
  50.1%   { transform: translate(var(--bk-sx), var(--bk-ty)) scale(1) rotateY(-90.2deg); filter: brightness(.82); opacity: 1; animation-timing-function: var(--turn-out); }
  74%     { transform: translate(var(--bk-sx), var(--bk-ty)) scale(1) rotateY(-180deg); filter: brightness(1); opacity: 1; animation-timing-function: var(--zoom-ease); }
  100%    { transform: translate(0px, 0px) scale(var(--bk-ik)) rotateY(-180deg); filter: brightness(1); opacity: 1; }
}
@keyframes bk-back-lifts {
  0%   { transform: translate(0px, 0px) scale(var(--bk-ik)) rotateY(-180deg); filter: brightness(1); opacity: 1; animation-timing-function: var(--zoom-ease); }
  26%  { transform: translate(var(--bk-sx), var(--bk-ty)) scale(1) rotateY(-180deg); filter: brightness(1); opacity: 1; animation-timing-function: var(--turn-in); }
  50%  { transform: translate(var(--bk-sx), var(--bk-ty)) scale(1) rotateY(-90deg); filter: brightness(.82); opacity: 1; }
  50.1%, 100% { transform: translate(var(--bk-sx), var(--bk-ty)) scale(1) rotateY(-90deg); filter: brightness(.82); opacity: 0; }
}

/* home: the page is lowered away and the book fades up in its place */
:root:active-view-transition-type(home)::view-transition-old(root) {
  mix-blend-mode: normal; animation: 1.2s cubic-bezier(.45, 0, .25, 1) both page-lowered;
}
:root:active-view-transition-type(home)::view-transition-new(root) {
  mix-blend-mode: normal; animation: 1.2s ease both book-up;
}
@keyframes page-lowered {
  0%   { transform: scale(1); opacity: 1; filter: drop-shadow(0 0 0 rgb(30 33 37 / 0)); }
  55%  { transform: scale(.6); opacity: 1; filter: drop-shadow(0 22px 34px rgb(30 33 37 / .3)); }
  100% { transform: scale(.5); opacity: 0; filter: drop-shadow(0 22px 34px rgb(30 33 37 / 0)); }
}
@keyframes book-up {
  0%, 50% { opacity: 0; }
  100% { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }      /* no page turn at all: just go to the page */
}
