/* transitions.css — cross-document View Transitions: the desk becomes the nav (board r2-01 A).
   Loaded on home and on every gateway page. The shared parts carry one name each; transitions.js
   (pagereveal) replaces the browser's default morph with keyframes sampled from the physics clock.
   Engines without cross-document View Transitions keep a hard cut; reduced motion gets no transition.
   The opt-in, @view-transition{navigation:auto} (none under reduced motion), is not here but in an inline <style>
   right before this sheet on every page: Chrome decides whether the page you land on takes the move from the opt-in
   it read when <body> went in, unless something restyles the page before its first frame, and a linked sheet is
   never in by then. From here it relied on site.js measuring the nav first; when the frame won (a render-blocking
   file a little late), the move was a hard cut and Chrome reported its skipped transition as an uncaught error. */

/* ---- names: one rendered element per name per document ---- */
.site-identity{view-transition-name:identity}
/* the header strip itself: its labels, status line and home link travel with the named parts in it, instead of
   crossing over inside the page (from a scrolled page that crossover showed two navs, one above the other) */
.site-shell-header{view-transition-name:site-head}
.site-index .site-nav-laptop,.desk-laptop{view-transition-name:obj-laptop}
.site-index .site-nav-book,.desk-book{view-transition-name:obj-book}
.site-index .site-nav-frame,.desk-frame{view-transition-name:obj-frame}
.site-index .site-nav-camera,.desk-camera{view-transition-name:obj-camera}
.site-rule{view-transition-name:site-rule}
.site-tabmark{view-transition-name:tabmark}
.desk-plate{view-transition-name:desk-table}
.desk-edge{view-transition-name:desk-edge}
.desk-mug{view-transition-name:desk-mug}
.desk-plant{view-transition-name:desk-plant}
.desk-bird{view-transition-name:desk-bird}
.desk-notes{view-transition-name:desk-notes}
/* the edge ↔ rule line, drawn live during home ↔ page (a snapshot can't sag or straighten) */
.fy-rule-live{view-transition-name:rule-live;position:fixed;left:0;top:0;width:100vw;height:100vh;z-index:2147483647;overflow:visible;pointer-events:none;fill:none;stroke-linecap:butt;stroke-linejoin:round}

/* ---- carried objects: transitions.js lays out each snapshot around its ink anchor ---- */
::view-transition-old(obj-laptop),::view-transition-new(obj-laptop),
::view-transition-old(obj-book),::view-transition-new(obj-book),
::view-transition-old(obj-frame),::view-transition-new(obj-frame),
::view-transition-old(obj-camera),::view-transition-new(obj-camera){left:0;top:0;transform-origin:0 0}
::view-transition-group(rule-live),::view-transition-new(rule-live){animation:none}
/* the carried objects fly over everything they pass (props, table, the live line under them) */
::view-transition-group(obj-laptop),::view-transition-group(obj-book),::view-transition-group(obj-frame),::view-transition-group(obj-camera){z-index:3}
::view-transition-group(rule-live){z-index:2}

/* ---- the page itself: the paper stays put while the rest crosses over (plus-lighter keeps it solid).
   The header strip exists on one side only here, so it keeps the page's timing ---- */
html[data-vt=enter]::view-transition-old(root),html[data-vt=enter]::view-transition-new(root),html[data-vt=enter]::view-transition-new(site-head){animation-duration:.3s;animation-delay:.16s;animation-timing-function:ease-in-out;animation-fill-mode:both}
html[data-vt=leave]::view-transition-old(root),html[data-vt=leave]::view-transition-new(root),html[data-vt=leave]::view-transition-old(site-head){animation-duration:.2s;animation-timing-function:ease-in;animation-fill-mode:both}
/* page → page: the sheet you leave is nearly gone before the next one comes up, so two layouts never share the
   screen at half strength (on a phone that double exposure fills the screen); what shows between is the paper */
html[data-vt=tab]::view-transition-old(root),html[data-vt=tab]::view-transition-old(site-head){animation-duration:.12s;animation-timing-function:cubic-bezier(.4,0,1,1);animation-fill-mode:both}
html[data-vt=tab]::view-transition-new(root),html[data-vt=tab]::view-transition-new(site-head){animation-duration:.2s;animation-delay:.07s;animation-timing-function:cubic-bezier(0,0,.2,1);animation-fill-mode:both}

/* ---- home → page: the props have no slot, so a held beat and then gravity (g 7000, 3600 on phones) ---- */
html[data-vt=enter]::view-transition-old(desk-mug){--w:50ms;--spin:-13deg}
html[data-vt=enter]::view-transition-old(desk-plant){--w:70ms;--spin:6deg}
html[data-vt=enter]::view-transition-old(desk-bird){--w:20ms;--spin:0deg}
html[data-vt=enter]::view-transition-old(desk-mug),html[data-vt=enter]::view-transition-old(desk-plant),html[data-vt=enter]::view-transition-old(desk-bird){
  --fall:219px;transform-origin:50% 100%;
  animation:fy-vt-fall .25s cubic-bezier(.333,0,.667,.333) var(--w) both,fy-vt-gone .16s cubic-bezier(.55,0,1,.45) calc(var(--w) + 90ms) both}
html[data-vt=enter]::view-transition-old(desk-notes){animation:fy-vt-gone .11s ease-in both}
html[data-vt=enter]::view-transition-old(desk-edge){animation:none;opacity:0}
@media (max-width:640px){
  html[data-vt=enter]::view-transition-old(desk-mug),html[data-vt=enter]::view-transition-old(desk-plant),html[data-vt=enter]::view-transition-old(desk-bird){--fall:112px}
}
@keyframes fy-vt-fall{to{transform:translateY(var(--fall)) rotate(var(--spin))}}
@keyframes fy-vt-gone{to{opacity:0}}

/* ---- page → home: the rule and the tab are handed to the live line and to transitions.js ---- */
html[data-vt=leave]::view-transition-old(site-rule){animation:none;opacity:0}

/* ---- page → page: the small marks a page answers with (transitions-tab.js), each its own group, so the
   compositor moves them: the printed page's edge and the laptop's caret, the camera's flash and its 咔嚓 ---- */
.fy-tab-edge,.fy-tab-caret,.fy-tab-flash,.fy-tab-kacha{position:fixed;left:0;top:0;z-index:2147483646;pointer-events:none}
.fy-tab-edge{view-transition-name:tab-edge;width:100vw;height:1.5px;background:var(--ink)}
.fy-tab-caret{view-transition-name:tab-caret;width:11px;height:20px;background:var(--ink)}
.fy-tab-flash{view-transition-name:tab-flash;width:92px;height:92px;border-radius:50%;background:#FFFDF6;box-shadow:inset 0 0 0 1.2px var(--ink)}
.fy-tab-kacha{view-transition-name:tab-kacha;font:22px/1 "DingTalk JinBuTi",serif;color:var(--ink);white-space:nowrap}
::view-transition-group(tab-edge),::view-transition-group(tab-caret),::view-transition-group(tab-flash),::view-transition-group(tab-kacha){z-index:4}

/* ---- the Building board ↔ a project's pages, and its chapters (FYProject, transitions-tab.js): the index tabs in play
   (.fy-vt-tabs: the dossier's in your hand or one card's peeking tabs on the board, the fore-edge on a project page),
   the card they belong to (.fy-vt-card: the card in your hand, or the card at rest with its pin) and, in your hand,
   the dossier's sheet their edges tuck under (.fy-vt-sheet), on the board only, named only for the move they travel
   in. The card's and the sheet's groups are above the tabs', as at rest, so a tab under them at rest is under them in
   every frame. A tab's group keeps its new box, never sized, and its images fill it; FYProject scales the old one
   back to its own size ---- */
.fy-vt-tabs>:is(.dos-tab,.dos-edge):nth-child(1){view-transition-name:pj-tab-1}
.fy-vt-tabs>:is(.dos-tab,.dos-edge):nth-child(2){view-transition-name:pj-tab-2}
.fy-vt-tabs>:is(.dos-tab,.dos-edge):nth-child(3){view-transition-name:pj-tab-3}
.fy-vt-tabs>:is(.dos-tab,.dos-edge):nth-child(4){view-transition-name:pj-tab-4}
.fy-vt-tabs>:is(.dos-tab,.dos-edge):nth-child(5){view-transition-name:pj-tab-5}
.fy-vt-card{view-transition-name:pj-card}
.fy-vt-sheet{view-transition-name:pj-sheet}
::view-transition-group(pj-tab-1),::view-transition-group(pj-tab-2),::view-transition-group(pj-tab-3),::view-transition-group(pj-tab-4),::view-transition-group(pj-tab-5){z-index:4}
::view-transition-group(pj-sheet){z-index:5}
::view-transition-group(pj-card){z-index:6}
::view-transition-old(pj-tab-1),::view-transition-new(pj-tab-1),::view-transition-old(pj-tab-2),::view-transition-new(pj-tab-2),::view-transition-old(pj-tab-3),::view-transition-new(pj-tab-3),
::view-transition-old(pj-tab-4),::view-transition-new(pj-tab-4),::view-transition-old(pj-tab-5),::view-transition-new(pj-tab-5){height:100%}

/* ---- Writing ↔ Reading: the book's cover becomes the essay's plate (FYBook, transitions-book.js). Named only for the move they
   travel in: the book's front board (.fy-book-cover, with the pages behind it hidden while it travels) and its obi on the
   shelf; on the essay the whole cover where the plate shows it (arriving) or the same drawn into a canvas (leaving) ---- */
.fy-book-cover{view-transition-name:book-cover}
.fy-book-obi{view-transition-name:book-obi}
.fy-book-lifted .p1,.fy-book-lifted .leaf-back{visibility:hidden}
/* the frame is a clip that holds still in the group's own box; the transform carries that box. Stacking: the page (root) < the frame < the obi < the header */
::view-transition-group(book-cover){z-index:1;overflow:clip}
::view-transition-group(book-obi){z-index:2}
html[data-vt=book]::view-transition-group(site-head),html[data-vt=book]::view-transition-group(identity),html[data-vt=book]::view-transition-group(site-rule),html[data-vt=book]::view-transition-group(tabmark){z-index:3}
/* the new header strip is whole from the first frame and the old one fades off it, on top (a fade out over a fade in lets bare paper through, and that read as the page reloading) */
html[data-vt=book]::view-transition-old(site-head){z-index:1}
/* the essay's intro laid out unseen where React will put it, and the cover as the plate shows it (paper under it at 50%) */
.rd-main.fy-book-intro{position:absolute;left:0;right:0;visibility:hidden;pointer-events:none}
.fy-book-photo{position:fixed;z-index:0;pointer-events:none;background:var(--paper);overflow:hidden}
.fy-book-photo img{display:block;width:100%;height:100%;object-fit:cover;opacity:.5;filter:saturate(.78) sepia(.05)}
html:not(:active-view-transition) .fy-book-photo{opacity:0}
.fy-book-shot{position:fixed;z-index:0;pointer-events:none}
html.dark .fy-book-photo img{opacity:.45;filter:saturate(.6) brightness(.92)}
html.dark .fy-book-photo::after{content:"";position:absolute;inset:0;background:var(--cap);opacity:var(--cap-a);mix-blend-mode:darken}
/* the browser's own animations of every part are held at their first frame until transitions-tab.js replaces them (data-vt-go):
   real Chrome can draw the first frame before that runs, and with them killed that frame was the move's last pose */
html[data-vt=book]:not([data-vt-go])::view-transition-group(*),html[data-vt=book]:not([data-vt-go])::view-transition-image-pair(*),html[data-vt=book]:not([data-vt-go])::view-transition-old(*),html[data-vt=book]:not([data-vt-go])::view-transition-new(*){animation-play-state:paused}
