/* Portfolio layer for 张倩云作品集: full-bleed leaves, prints with their captions, artwork across the gutter,
   the index of plates and typographic pages. Loaded after styles.css; the bundled reader and default page
   styles stay untouched. */
@font-face{font-family:"Noto Serif SC Book";src:url("assets/fonts/noto-serif-sc-400.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"Noto Serif SC Book";src:url("assets/fonts/noto-serif-sc-600.woff2") format("woff2");font-weight:600;font-style:normal;font-display:swap}
:root{--book-serif:"Source Serif 4","Noto Serif SC Book","Songti SC","Noto Serif CJK SC",Georgia,serif;--paper:#fbfaf6;--ink:#2b2926;--cloth:#d8d3c8;
  --quiet:#86837c;--rule:rgb(43 41 38 / 13%);--accent:#b35a34;--night:#0f1115;--night-ink:#e8e4db;--night-quiet:rgb(232 228 219 / 50%)}
.art-page.endpaper{background-color:#dce1e2}
.art-page.cloth{color:var(--ink)}
.art-page.night{background-color:var(--night);color:var(--night-ink)}

/* Photographs that fill the leaf edge to edge. */
.art-page img.bleed{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}

/* Prints with paper around them, sized to the photograph; the caption hangs just under the image. */
.art-page .print{position:absolute;margin:0}
.art-page .print img{width:100%;height:100%;object-fit:cover}
.art-page .cap{position:absolute;margin:0;font:400 2.15cqw/1.4 var(--book-serif);letter-spacing:.06em;color:var(--quiet);white-space:nowrap}
.cap span,.phone-caption p span{margin-right:1.3em;font:400 1.75cqw/1 var(--book-sans);letter-spacing:.14em}
.night .cap{color:var(--night-quiet)}

/* One photograph laid across a spread: each leaf shows its own half of a shared canvas. */
.spread-window{position:absolute;inset:0;overflow:hidden}
.spread-canvas{position:absolute;inset-block:0;left:0;width:200%}
.recto .spread-canvas{left:-100%}
.spread-canvas img{position:absolute;object-fit:cover}

/* Single-page (phone) layout: show the whole photograph on the first leaf, its caption on the second. */
.phone-caption{display:none}
.book[data-layout="portrait"] .phone-whole .spread-canvas{left:0;width:100%}
.book[data-layout="portrait"] .phone-whole .spread-canvas img{left:5%!important;width:90%!important;top:50%!important;height:auto!important;transform:translateY(-50%)}
.book[data-layout="portrait"] .phone-whole.recto .spread-window{display:none}
.book[data-layout="portrait"] .phone-whole.recto .phone-caption{display:block;position:absolute;left:15%;right:13%;top:42%}
.phone-caption p{margin:0;font:400 3.4cqw/1.7 var(--book-serif);color:var(--ink)}
.phone-caption .k{font:400 2.6cqw/1.5 var(--book-sans);letter-spacing:.08em;color:var(--quiet);margin:0 0 3cqw}
.night .phone-caption p{color:var(--night-ink)}
.night .phone-caption .k{color:var(--night-quiet)}

/* Phones: the drop shadow is a filter over the whole book and is redrawn on every frame of a turn, which made
   turning stutter; the paper edge reads against the wall without it. */
.book[data-layout="portrait"]{filter:none}

/* A leaf whose photographs are still on their way shows a quiet pulse instead of bare paper. */
.book-page.art-page[data-loading]::after{content:"";position:absolute;left:50%;top:50%;z-index:2;width:22px;height:22px;margin:-11px 0 0 -11px;border:1px solid rgb(43 41 38 / 24%);border-radius:50%;animation:leaf-loading 1.4s ease-in-out infinite}
.book-page.art-page.night[data-loading]::after{border-color:rgb(232 228 219 / 30%)}
@keyframes leaf-loading{50%{transform:scale(1.5);opacity:.3}}
@media (prefers-reduced-motion:reduce){.book-page.art-page[data-loading]::after{animation:none}}

/* Typographic leaves. */
.art-page .type{position:absolute;left:15%;right:13%;margin:0}
.art-page .cover-title.zh{font-size:11cqw;letter-spacing:.14em;top:13%;text-shadow:0 1px 0 rgb(255 255 255 / 42%)} /* pressed into the linen */
.art-page .cover-subtitle{top:30%;font-size:3cqw;letter-spacing:.08em}
.art-page .cover-plate{bottom:15%;width:52%;padding:1.5cqw;background:var(--paper);box-shadow:0 1px 2px rgb(40 34 26 / 22%),0 8px 18px rgb(40 34 26 / 10%)}
.art-page .back-mark{font-size:2.8cqw;letter-spacing:.08em}
.title-page{top:29%}
.title-page h2{font:400 9.5cqw/1.1 var(--book-serif);letter-spacing:.14em;margin:0 0 2.5cqw}
.title-page .en{font:italic 400 4.6cqw/1.2 var(--book-serif);margin:0 0 13cqw}
.title-page .meta,.chapter .meta{font:400 2.9cqw/1.8 var(--book-serif);color:var(--quiet);margin:0}
.contents{top:14%}
.contents h2{font:400 4.8cqw/1.2 var(--book-serif);letter-spacing:.08em;margin:0 0 1.4cqw}
.contents .sub{font:400 2.3cqw/1.4 var(--book-sans);letter-spacing:.22em;text-transform:uppercase;color:var(--quiet);margin:0 0 6cqw}
.contents ol{list-style:none;margin:0;padding:0}
.contents a{display:grid;grid-template-columns:7.5cqw 1fr auto;align-items:baseline;gap:2cqw;padding:2.1cqw 0;border-top:1px solid var(--rule);color:inherit;text-decoration:none;cursor:pointer}
.contents li:last-child a{border-bottom:1px solid var(--rule)}
.contents li.extra a{margin-top:3.4cqw}
.contents a>*{pointer-events:none}
.contents .n,.contents .p{font:400 2.4cqw/1 var(--book-sans);letter-spacing:.1em;color:var(--quiet)}
.contents .t{font:400 3.6cqw/1.3 var(--book-serif)}
.contents .t em{display:block;margin-top:.4cqw;font-size:2.6cqw;color:var(--quiet)}
.contents a:hover .t,.contents a:focus-visible .t{color:var(--accent)}
.chapter{top:31%}
.chapter .num{font:400 2.6cqw/1 var(--book-sans);letter-spacing:.24em;color:var(--quiet);margin:0 0 7cqw}
.chapter h2{font:400 8cqw/1.18 var(--book-serif);letter-spacing:.08em;margin:0 0 2.6cqw}
.chapter .en{font:italic 400 4.4cqw/1.3 var(--book-serif);color:#55524c;margin:0 0 10cqw}
.chapter .count{letter-spacing:.04em}
.chapter-numeral{position:absolute;left:10%;bottom:6%;margin:0;font:400 46cqw/.8 var(--book-serif);letter-spacing:-.04em;color:rgb(43 41 38 / 6%)}
.night .chapter .num,.night .chapter .meta{color:var(--night-quiet)}
.night .chapter .en{color:rgb(232 228 219 / 74%)}
.night .chapter-numeral{color:rgb(232 228 219 / 7%)}
.colophon-page{top:28%}
.colophon-page h2{font:400 4.8cqw/1.25 var(--book-serif);letter-spacing:.08em;margin:0 0 1.4cqw}
.colophon-page .en{font:italic 400 3cqw/1.3 var(--book-serif);margin:0 0 7cqw;color:#55524c}
.colophon-page p{font:400 2.7cqw/1.75 var(--book-serif);margin:0 0 3.2cqw}
.colophon-page .small{font:400 2.25cqw/1.7 var(--book-sans);color:var(--quiet)}

/* Index of plates: every photograph as a small print, its number, title and page; a tap turns to it. */
.plates{position:absolute;inset:9.5% 10.5% 7%}
.plates h2{font:400 4.8cqw/1.2 var(--book-serif);letter-spacing:.08em;margin:0 0 1.2cqw}
.plates .sub{font:400 2.2cqw/1.4 var(--book-sans);letter-spacing:.22em;text-transform:uppercase;color:var(--quiet);margin:0 0 5.4cqw}
.plates .sub.cont{margin:0 0 12.2cqw;font-family:var(--book-serif);letter-spacing:.16em;text-transform:none}
.plates ol{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:4.4cqw 3.2cqw}
.plates a{display:grid;grid-template-columns:1fr auto;align-items:baseline;gap:1cqw .6cqw;color:inherit;text-decoration:none;cursor:pointer}
.plates a>*{pointer-events:none}
.plates img{grid-column:1/-1;width:100%;aspect-ratio:3/4;object-fit:cover;background:#ece9e2;margin-bottom:.4cqw;transition:opacity .3s}
.plates .n,.plates .p{font:400 1.7cqw/1.2 var(--book-sans);letter-spacing:.12em;color:var(--quiet)}
.plates .t{grid-column:1/-1;font:400 2.05cqw/1.35 var(--book-serif);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.plates a:hover img,.plates a:focus-visible img{opacity:.82}
.plates a:hover .t,.plates a:focus-visible .t{color:var(--accent)}
.plates .note{position:absolute;left:0;bottom:0;margin:0;font:400 1.9cqw/1.6 var(--book-sans);letter-spacing:.06em;color:var(--quiet)}


/* ===== The exhibition room ===================================================================================
   Everything outside the leaves. The book hangs on a white wall in daylight; the work on view tints the wall
   faintly with its own colour, and a few flakes of snow drift past. An entrance comes first: a ring of every
   photograph around the title. Wide screens hang a wall label and a large wall title beside the book, the
   route of the seven rooms runs along the bottom, and a guide lists the rooms. exhibit.js drives it. */
:root{--wall:#efede8;--wall-hi:#f8f6f2;--wall-lo:#e2dfd8;--ink-2:rgb(43 41 38 / 66%);--ink-3:rgb(43 41 38 / 44%);--ink-4:rgb(43 41 38 / 12%);
  --ease:cubic-bezier(.2,.7,.1,1);--ui-sans:"Helvetica Neue",Helvetica,Arial,"PingFang SC","Microsoft YaHei",sans-serif;
  --chrome:176px;--side:clamp(240px,20vw,380px);background:var(--wall)}
html,body{background:var(--wall)}
body{color:var(--ink)}
.room{position:relative;isolation:isolate;overflow:hidden;padding:max(18px,env(safe-area-inset-top)) clamp(18px,3vw,48px) max(14px,env(safe-area-inset-bottom));color:var(--ink)}
button:focus-visible{outline:1px solid var(--ink-2);outline-offset:4px}

/* Light and air: a bright wall that falls off towards the corners, the work's own colour on the wall around
   it, soft bands of window light that move very slowly, a few flakes of snow and a fine still grain.
   Only opacity and transforms ever animate. */
.ambience{position:absolute;inset:0;z-index:-1;overflow:hidden;pointer-events:none;background:radial-gradient(125% 110% at 50% 44%,var(--wall-hi) 0%,var(--wall) 52%,var(--wall-lo) 100%)}
.ambience>*{position:absolute}
.glow{inset:-14%;opacity:0;transform:translate3d(calc(var(--px,0) * -14px),calc(var(--py,0) * -10px),0);transition:opacity 2s var(--ease);
  background:radial-gradient(56% 58% at 50% 50%,rgb(var(--tone,204 198 188) / 24%),rgb(var(--tone,204 198 188) / 11%) 40%,rgb(var(--tone,204 198 188) / 3%) 66%,transparent 86%)}
.glow.is-on{opacity:1}
.daylight{inset:-30% -20%;opacity:.95;transform:translate3d(calc(var(--px,0) * 22px),calc(var(--py,0) * 10px),0);
  background:linear-gradient(116deg,transparent 18%,rgb(255 255 255 / 0) 24%,rgb(255 255 255 / 62%) 31%,rgb(255 255 255 / 0) 40%,transparent 46%,rgb(255 255 255 / 0) 50%,rgb(255 255 255 / 44%) 55%,rgb(255 255 255 / 0) 62%)}
.daylight::after{content:"";position:absolute;inset:0;background:inherit;opacity:.5;animation:sun 70s ease-in-out infinite alternate}
@keyframes sun{to{transform:translate3d(7%,1%,0)}}
.snow{inset:0}
.snow i{position:absolute;left:var(--x);top:-12px;width:var(--s);height:var(--s);border-radius:50%;opacity:0;background:rgb(132 150 168 / 70%);animation:flake var(--d) linear var(--delay) infinite}
@keyframes flake{0%{opacity:0;transform:translate3d(0,0,0)}12%,80%{opacity:var(--o)}100%{opacity:0;transform:translate3d(var(--dx),104vh,0)}}
.grain{inset:0;opacity:.05;
  background:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='180' height='180'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .6 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>")}
.room.is-turning .snow i,.room.is-turning .daylight::after{animation-play-state:paused} /* the turn gets the whole frame */
/* The night room: the gallery lights come down a little, most at the edges of the wall. */
.ambience::after{content:"";position:absolute;inset:0;opacity:0;transition:opacity 2.6s var(--ease);
  background:radial-gradient(110% 95% at 50% 46%,rgb(22 24 32 / 6%) 0%,rgb(22 24 32 / 22%) 55%,rgb(22 24 32 / 44%) 100%)}
.room.is-night .ambience::after{opacity:1}
.room.is-night .snow i{background:rgb(236 240 246 / 80%)}

/* The book hangs larger on big screens, keeping room beside it for the label and the wall title. */
.stage{z-index:1}
.book-rig{--book-h:min(calc(100dvh - var(--chrome)),calc((100vw - 2 * var(--side)) / (2 * var(--page-ratio))),780px);width:min(100%,calc(var(--book-h) * var(--page-ratio) * 2));height:var(--book-h)}
.book{filter:drop-shadow(0 26px 30px rgb(58 48 36 / 20%)) drop-shadow(0 4px 8px rgb(58 48 36 / 13%))}

/* Header: the name on the left, the guide and full screen on the right. */
.book-header{position:relative;z-index:3;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:10px 24px;width:100%;margin:0}
.brand{display:flex;align-items:baseline;gap:20px;min-width:0}
.book-header h1{margin:0;font:600 19px/1 var(--book-serif);letter-spacing:.5em;color:var(--ink)}
.book-header .brand-en{font:400 10px/1 var(--ui-sans);letter-spacing:.34em;text-transform:uppercase;white-space:nowrap;color:var(--ink-3)}
.tools{display:flex;align-items:center;gap:2px}
.tool{display:inline-flex;align-items:center;gap:10px;height:40px;padding:0 12px;border:0;background:none;color:var(--ink-2);font:400 13px/1 var(--book-serif);letter-spacing:.3em;cursor:pointer;transition:color .4s}
.tool em{font:400 10px/1 var(--ui-sans);font-style:normal;letter-spacing:.3em;text-transform:uppercase;color:var(--ink-3);transition:color .4s}
.tool:hover,.tool:hover em{color:var(--ink)}
.tool-icon svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.1}
#chapter-label{display:none}

/* The label and the wall title hang off the book itself: the label at its lower left, the title at its upper
   right. With only the cover (or the back) showing, the book sits a quarter further in, and so do they. */
.book-rig{--gap:clamp(28px,3vw,56px);--inset:0%;position:relative}
.room[data-edge="front"] .book-rig,.room[data-edge="back"] .book-rig{--inset:25%}

/* Wall label, museum style; under it, the works on the open leaves. */
.wall-label{position:absolute;right:calc(100% + var(--gap) - var(--inset));bottom:0;z-index:3;display:none;width:clamp(150px,13vw,230px);transition:right .76s ease,opacity 1.2s var(--ease)}
.wall-label p,.wall-label h2{margin:0}
.wall-label .wl-room{font:400 10px/1.6 var(--ui-sans);letter-spacing:.34em;text-transform:uppercase;color:var(--ink-3)}
.wl-room b{font-weight:400;color:var(--accent)}
.wall-label .wl-title{margin:26px 0 10px;font:600 clamp(28px,2.3vw,36px)/1.22 var(--book-serif);letter-spacing:.14em;color:var(--ink)}
.wall-label .wl-en{margin-bottom:30px;font:italic 400 17px/1.4 "Source Serif 4",Georgia,serif;color:var(--ink-2)}
.wall-label .wl-kind{font:400 13px/1.9 var(--book-serif);letter-spacing:.08em;color:var(--ink-2)}
.wl-kind span{display:block;font:400 11px/1.7 var(--ui-sans);letter-spacing:.06em;color:var(--ink-3)}
.wall-label .wl-years{margin-top:8px;font:400 11px/1.6 var(--ui-sans);letter-spacing:.2em;font-variant-numeric:tabular-nums;color:var(--ink-3)}
.wl-rule{display:block;width:40px;height:1px;margin-top:28px;background:var(--accent);transform-origin:left}
.wl-head.is-leaving>*{opacity:0;transform:translate3d(0,-8px,0);transition:opacity .3s ease,transform .3s ease}
.wl-head.is-entering>*{animation:wl-in 1s var(--ease) backwards}
.wl-head.is-entering>:nth-child(2){animation-delay:.07s}
.wl-head.is-entering>:nth-child(3){animation-delay:.14s}
.wl-head.is-entering>:nth-child(4){animation-delay:.21s}
.wl-head.is-entering>:nth-child(5){animation-delay:.28s}
.wl-head.is-entering .wl-rule{animation:wl-rule 1.3s var(--ease) .32s backwards}
@keyframes wl-in{from{opacity:0;transform:translate3d(0,14px,0)}}
@keyframes wl-rule{from{transform:scaleX(0)}}
.wl-works{display:grid;gap:7px;margin:18px 0 0;padding:0;list-style:none;transition:opacity .35s ease}
.wl-works.is-swapping{opacity:0}
.wl-works li{display:grid;grid-template-columns:30px 1fr;font:400 13px/1.5 var(--book-serif);letter-spacing:.06em;color:var(--ink)}
.wl-works b{font:400 10px/2 var(--ui-sans);letter-spacing:.14em;color:var(--ink-3)}
.wl-works li.ai{color:var(--ink-2)}
.wl-works li.ai b{color:var(--accent)}

/* Wall title: the room's name in large outlined vertical type. */
.wall-title{position:absolute;top:0;left:calc(100% + var(--gap) - var(--inset));z-index:0;display:none;pointer-events:none;transform:translate3d(calc(var(--px,0) * -10px),calc(var(--py,0) * -6px),0);transition:left .76s ease}
.wt{position:absolute;top:0;left:0;display:flex;align-items:flex-start;gap:20px;margin:0;opacity:0;transform:translate3d(0,16px,0);transition:opacity 1.4s var(--ease),transform 1.9s var(--ease)}
.wt.is-on{opacity:1;transform:none}
.wt-zh{writing-mode:vertical-rl;font:600 min(148px,calc(var(--book-h) * .92 / var(--n,2) / 1.22))/1 var(--book-serif);letter-spacing:.22em;color:rgb(43 41 38 / 2.5%);-webkit-text-stroke:1px rgb(43 41 38 / 15%)}
.wt-en{writing-mode:vertical-rl;padding-top:.3em;font:400 10px/1 var(--ui-sans);letter-spacing:.46em;text-transform:uppercase;white-space:nowrap;color:var(--ink-3)}

/* Bottom: how to turn, the route of the seven rooms, the page count. */
.controls{position:relative;z-index:3;display:grid;grid-template-columns:minmax(0,1fr) minmax(0,min(760px,58vw)) minmax(0,1fr);align-items:end;gap:28px;width:100%;margin:0}
.hint{justify-self:start;margin:0;font:400 12px/1.5 var(--book-serif);letter-spacing:.16em;color:var(--ink-3);transition:opacity 1.2s var(--ease)}
.room.has-turned .hint{opacity:0}
.route{display:flex;gap:6px;margin:0;padding:0;list-style:none}
.route li{position:relative;flex:1 1 0;min-width:0}
.controls .route button{display:grid;gap:9px;width:100%;height:auto;padding:12px 0 6px;border:0;border-radius:0;background:none;color:var(--ink-3);text-align:left;font:inherit;cursor:pointer}
.route-num{font:400 10px/1 var(--ui-sans);letter-spacing:.22em;transition:color .5s}
.route-name{position:absolute;left:0;bottom:calc(100% - 2px);white-space:nowrap;font:400 12px/1 var(--book-serif);letter-spacing:.16em;color:var(--ink);opacity:0;transform:translate3d(0,4px,0);transition:opacity .35s,transform .35s;pointer-events:none}
.route button:hover .route-name{opacity:1;transform:none}
.route-bar{position:relative;display:block;height:1px;overflow:hidden;background:var(--ink-4);transition:height .5s var(--ease)}
.route-bar i{position:absolute;inset:0;background:var(--ink-3);transform-origin:left;transform:scaleX(var(--fill,0));transition:transform 1s var(--ease)}
.route li[data-state="here"] .route-num,.route button:hover .route-num{color:var(--ink)}
.route li[data-state="here"] .route-bar{height:2px}
.route li[data-state="here"] .route-bar i{background:var(--accent)}
.pager{justify-self:end;display:flex;align-items:center;gap:14px}
.status span{display:inline-block;font:400 11px/1 var(--ui-sans);letter-spacing:.26em;font-variant-numeric:tabular-nums;color:var(--ink-2)}
.status span.tick{animation:tick .6s var(--ease)}
@keyframes tick{from{opacity:0;transform:translate3d(0,7px,0)}}
#previous svg,#next svg{fill:none;stroke:currentColor;stroke-width:1}

/* Turning arrows stand at the edges of the room on anything wider than a phone. */
@media (min-width:701px){
  #previous,#next{position:fixed;top:50%;z-index:5;display:grid;place-items:center;width:58px;height:150px;margin:-75px 0 0;padding:0;border:0;border-radius:0;background:none;color:var(--ink);opacity:.34;cursor:pointer;transition:opacity .45s var(--ease),translate .6s var(--ease)}
  #previous{left:max(6px,env(safe-area-inset-left))}
  #next{right:max(6px,env(safe-area-inset-right))}
  #previous svg,#next svg{width:40px;height:12px}
  #previous:not(:disabled):hover{opacity:1;translate:-6px 0}
  #next:not(:disabled):hover{opacity:1;translate:6px 0}
  #previous:disabled,#next:disabled{opacity:.07;cursor:default}
}

/* Quiet mode: when the visitor only looks, the signage fades and the work stays. */
.book-header,.controls{transition:opacity 1.2s var(--ease)}
.room.is-idle .book-header,.room.is-idle .controls{opacity:.08}
.room.is-idle .wall-label{opacity:.45}
.room.is-idle #previous,.room.is-idle #next{opacity:0}
.room.is-idle .controls:hover{opacity:1}

/* Coming in from the entrance: the room lights up, the book rises into its light, then the signage. */
@keyframes room-in{from{opacity:0}}
@keyframes rise-in{from{opacity:0;transform:translate3d(0,16px,0)}}
@keyframes stage-in{from{opacity:0;transform:translate3d(0,28px,0) scale(.985)}}
.room:not([data-phase="entrance"]) .stage{animation:stage-in 1.8s var(--ease) .5s backwards}
.room:not([data-phase="entrance"]) .book-header{animation:rise-in 1.3s var(--ease) 1s backwards}
.room:not([data-phase="entrance"]) .wall-label{animation:room-in 1.4s var(--ease) 1.15s backwards}
.room:not([data-phase="entrance"]) .wall-title{animation:room-in 2.2s var(--ease) 1.25s backwards}
.room:not([data-phase="entrance"]) .controls{animation:rise-in 1.3s var(--ease) 1.25s backwards}
.room:not([data-phase="entrance"]) #previous,.room:not([data-phase="entrance"]) #next{animation:room-in 1.4s var(--ease) 1.55s backwards}

/* Entrance: the exhibition's title inside a ring of every photograph. The ring turns slowly by itself and
   follows a drag, a swipe, the wheel or the arrow keys; a print opens the book at its page. On phones the
   ring becomes an arc of larger prints above the title. Each print is placed by exhibit.js every frame. */
.entrance{position:fixed;inset:0;z-index:40;overflow:hidden;background:radial-gradient(118% 100% at 50% 46%,var(--wall-hi) 0%,var(--wall) 56%,var(--wall-lo) 100%);color:var(--ink);
  -webkit-user-select:none;user-select:none;transition:opacity 1.1s var(--ease) .45s,visibility 0s linear 1.6s}
.entrance::before{content:"";position:absolute;inset:-30% -20%;pointer-events:none;opacity:.8;background:linear-gradient(116deg,transparent 22%,rgb(255 255 255 / 58%) 31%,transparent 41%,transparent 50%,rgb(255 255 255 / 40%) 56%,transparent 63%)}
/* While it fades it still takes every pointer event: on touch screens the browser sends mouse events after the
   tap that chose a print, and those must not reach the book underneath and turn it. */
.room[data-phase="entering"] .entrance{opacity:0;visibility:hidden}
.ring{position:absolute;inset:0;touch-action:none;outline:none;cursor:grab}
.ring.is-dragging{cursor:grabbing}
.ring:focus-visible::after{content:"";position:absolute;inset:10px;border:1px solid var(--ink-3);pointer-events:none}
.ring-plane{position:absolute;inset:0;transform:perspective(1500px) rotateX(calc(var(--ty,0) * 1deg)) rotateY(calc(var(--tx,0) * 1deg))}
.card{position:absolute;left:50%;top:50%;display:block;width:180px;aspect-ratio:3/4;margin:0;padding:0;border:0;background:#e9e6df;visibility:hidden;cursor:pointer;
  box-shadow:0 14px 26px rgb(52 44 34 / 15%),0 2px 5px rgb(52 44 34 / 12%);outline:1px solid rgb(255 255 255 / 60%);outline-offset:-1px;will-change:transform,opacity;-webkit-tap-highlight-color:transparent}
.card img{display:block;width:100%;height:100%;object-fit:cover;pointer-events:none;-webkit-user-drag:none}
.card:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
.entrance-copy{position:absolute;left:50%;top:50%;z-index:2;display:grid;justify-items:center;width:max-content;max-width:calc(100vw - 48px);text-align:center;pointer-events:none;
  transform:translate(-50%,-50%) scale(var(--copy-scale,1));transition:opacity .7s var(--ease),transform 1s var(--ease)}
.room[data-phase="entering"] .entrance-copy{opacity:0;transform:translate(-50%,calc(-50% - 20px)) scale(var(--copy-scale,1))}
.entrance-copy>*{margin:0;animation:intro-in 1.4s var(--ease) backwards}
@keyframes intro-in{from{opacity:0;transform:translate3d(0,22px,0)}}
.entrance .kicker{display:flex;gap:22px;font:400 11px/1 var(--ui-sans);letter-spacing:.44em;text-transform:uppercase;color:var(--ink-3);animation-delay:.25s}
.entrance .name{display:flex;gap:.2em;margin:.34em 0 .22em;padding-left:.2em;font:600 clamp(54px,6.4vw,116px)/1 var(--book-serif);letter-spacing:0;animation:none}
.name span{display:inline-block;animation:name-in 1.8s var(--ease) backwards}
.name span:nth-child(1){animation-delay:.4s}
.name span:nth-child(2){animation-delay:.55s}
.name span:nth-child(3){animation-delay:.7s}
@keyframes name-in{from{opacity:0;transform:translate3d(0,.32em,0);filter:blur(12px)}}
.entrance .name-en{font:italic 400 clamp(18px,1.6vw,24px)/1.3 "Source Serif 4",Georgia,serif;color:var(--ink-2);animation-delay:.85s}
.entrance .subtitle{margin-top:12px;padding-left:.6em;font:400 clamp(13px,1.05vw,16px)/1.6 var(--book-serif);letter-spacing:.6em;color:var(--ink-2);animation-delay:.95s}
.entrance .rule{display:block;width:56px;height:1px;margin:26px 0 24px;background:var(--accent);animation:rule-in 1.4s var(--ease) 1.1s backwards}
@keyframes rule-in{from{transform:scaleX(0)}}
.entrance .enter{display:inline-flex;align-items:center;gap:16px;padding:15px 22px 15px 28px;border:1px solid rgb(43 41 38 / 30%);background:rgb(255 255 255 / 36%);color:var(--ink);font:400 14px/1 var(--book-serif);letter-spacing:.42em;cursor:pointer;pointer-events:auto;
  transition:background .5s var(--ease),color .5s var(--ease),border-color .5s var(--ease);animation:intro-in 1.4s var(--ease) 1.3s backwards,breathe 3.8s ease-in-out 3.2s infinite}
.enter em{font:italic 400 15px/1 "Source Serif 4",Georgia,serif;letter-spacing:.04em;color:var(--ink-2);transition:color .5s}
.enter svg{width:30px;height:10px;fill:none;stroke:currentColor;stroke-width:1;transition:transform .6s var(--ease)}
.enter:hover,.enter:focus-visible{border-color:var(--ink);background:var(--ink);color:var(--wall-hi)}
.enter:hover em,.enter:focus-visible em{color:var(--wall-hi)}
.enter:hover svg{transform:translateX(6px)}
@keyframes breathe{50%{box-shadow:0 0 0 7px rgb(43 41 38 / 5%)}}
.ring-caption{position:absolute;left:clamp(24px,4vw,64px);bottom:max(64px,calc(env(safe-area-inset-bottom) + 52px));z-index:2;margin:0;pointer-events:none;animation:intro-in 1.4s var(--ease) 1.6s backwards;transition:opacity .7s var(--ease)}
.room[data-phase="entering"] .ring-caption{opacity:0}
.ring-caption p{margin:0}
.rc-room{font:400 10px/1.6 var(--ui-sans);letter-spacing:.32em;color:var(--ink-3)}
.rc-title{margin-top:6px!important;font:400 17px/1.4 var(--book-serif);letter-spacing:.12em;color:var(--ink)}
.rc-title b{margin-right:12px;font:400 11px/1 var(--ui-sans);letter-spacing:.14em;color:var(--accent)}
.entrance-foot{position:absolute;left:clamp(24px,4vw,64px);right:clamp(24px,4vw,64px);bottom:max(24px,env(safe-area-inset-bottom));z-index:2;display:flex;justify-content:space-between;gap:20px;margin:0;
  font:400 11px/1.4 var(--book-serif);letter-spacing:.26em;color:var(--ink-3);pointer-events:none;animation:intro-in 1.4s var(--ease) 1.7s backwards;transition:opacity .6s var(--ease)}
.room[data-phase="entering"] .entrance-foot{opacity:0}

/* Guide: the seven rooms as a list; a small print of each follows the pointer. */
.guide{position:fixed;inset:0;z-index:30;display:grid;place-items:center;padding:24px;background:rgb(241 239 234 / 0);transition:background .55s var(--ease)}
.guide[hidden]{display:none}
.room.guide-open .guide{background:rgb(241 239 234 / 95%);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px)}
.guide-inner{width:min(960px,100%);max-height:calc(100dvh - 48px);overflow:auto;opacity:0;transform:translate3d(0,18px,0);transition:opacity .5s var(--ease),transform .8s var(--ease)}
.room.guide-open .guide-inner{opacity:1;transform:none}
.guide-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:22px}
.guide-head p{margin:0;font:400 14px/1 var(--book-serif);letter-spacing:.4em;color:var(--ink)}
.guide-head em,.guide-foot em{margin-left:14px;font:400 10px/1 var(--ui-sans);font-style:normal;letter-spacing:.32em;text-transform:uppercase;color:var(--ink-3)}
.guide-close{display:grid;place-items:center;width:46px;height:46px;padding:0;border:0;background:none;color:var(--ink-2);cursor:pointer;transition:color .3s,transform .6s var(--ease)}
.guide-close:hover{color:var(--ink);transform:rotate(90deg)}
.guide-close svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1}
.guide-list{margin:0;padding:0;list-style:none;border-top:1px solid var(--ink-4)}
.guide-list button{display:grid;grid-template-columns:72px minmax(0,1fr) auto;grid-template-areas:"num zh meta" "num en meta";align-items:baseline;column-gap:28px;width:100%;padding:clamp(12px,2vh,20px) 6px;border:0;border-bottom:1px solid var(--ink-4);background:none;color:var(--ink);text-align:left;cursor:pointer;transition:padding .6s var(--ease),background .6s var(--ease)}
.guide-list button:hover,.guide-list button:focus-visible{padding-left:22px;background:linear-gradient(90deg,rgb(43 41 38 / 4%),transparent 70%)}
.g-num{grid-area:num;font:400 11px/1 var(--ui-sans);letter-spacing:.26em;color:var(--ink-3);transition:color .4s}
.guide-list button:hover .g-num{color:var(--accent)}
.g-zh{grid-area:zh;font:600 clamp(22px,min(2.6vw,3.6vh),36px)/1.15 var(--book-serif);letter-spacing:.16em}
.g-en{grid-area:en;margin-top:6px;font:italic 400 15px/1.4 "Source Serif 4",Georgia,serif;color:var(--ink-2)}
.g-meta{grid-area:meta;font:400 12px/1.8 var(--book-serif);letter-spacing:.08em;text-align:right;color:var(--ink-3)}
.room.guide-open .guide-list li{animation:rise-in .9s var(--ease) backwards;animation-delay:calc(var(--i) * 55ms + 120ms)}
.guide-foot{display:flex;flex-wrap:wrap;gap:8px;margin-top:22px}
.guide-foot button{padding:12px 14px;border:0;background:none;color:var(--ink-2);font:400 13px/1 var(--book-serif);letter-spacing:.3em;cursor:pointer;transition:color .3s}
.guide-foot button:hover{color:var(--ink)}
.guide-preview{position:fixed;left:0;top:0;z-index:31;width:240px;height:320px;margin:0;overflow:hidden;pointer-events:none;opacity:0;box-shadow:0 30px 60px rgb(52 44 34 / 26%);transition:opacity .45s var(--ease)}
.guide-preview img{display:block;width:100%;height:100%;object-fit:cover;transform:scale(1.1);transition:transform 1.2s var(--ease)}
.guide-preview.is-on{opacity:1}
.guide-preview.is-on img{transform:scale(1)}
@media (hover:none){.guide-preview{display:none}}

/* Touch screens are told once how to turn. */
.swipe-hint{position:absolute;top:58%;left:50%;z-index:6;display:flex;align-items:center;gap:14px;margin:0;padding:12px 18px;translate:-50% 0;border-radius:999px;background:rgb(43 41 38 / 82%);font:400 12px/1 var(--book-serif);letter-spacing:.24em;color:#f6f4ef;opacity:0;pointer-events:none;transition:opacity .7s var(--ease)}
.room.show-swipe-hint .swipe-hint{opacity:1}
.swipe-hint i{position:relative;width:18px;height:1px;background:currentColor}
.swipe-hint i::before{content:"";position:absolute;top:-3px;width:7px;height:7px;border:solid currentColor;border-width:1px 0 0 1px}
.swipe-hint i:first-child{--dir:-1}
.swipe-hint i:first-child::before{left:0;transform:rotate(-45deg)}
.swipe-hint i:last-child{--dir:1}
.swipe-hint i:last-child::before{right:0;transform:rotate(135deg)}
.room.show-swipe-hint .swipe-hint i{animation:nudge 1.4s ease-in-out infinite}
@keyframes nudge{50%{transform:translateX(calc(var(--dir) * 5px))}}

/* Screen sizes: wide screens hang the label and the wall title beside the book; narrower ones put the room's
   name under the header; phones stack everything and turn by swiping. */
@media (min-width:1200px){.wall-label,.wall-title{display:block}}
@media (max-width:1199px){
  :root{--side:64px;--chrome:206px}
  #chapter-label{display:block;order:3;flex-basis:100%;font:400 12px/1.5 var(--book-serif);letter-spacing:.14em;text-align:center;color:var(--ink-2)}
}
@media (max-width:700px){
  :root{--chrome:196px;--wall:#ebe8e2;--wall-hi:#f3f1ec}
  .room{padding:max(12px,env(safe-area-inset-top)) 12px max(8px,env(safe-area-inset-bottom))}
  .book-header{gap:6px 12px}
  .book-header h1{font-size:16px;letter-spacing:.42em}
  .book-header .brand-en,.tool em{display:none}
  .tool{padding:0 4px 0 12px}
  #chapter-label{font-size:11px;text-align:left}
  /* Exactly one page tall: PageFlip then has nothing to centre, so the leaf below never peeks out by a
     fraction of a pixel; the light from above fills the space over the book instead. */
  .stage{align-content:end}
  .book-rig{width:100%;height:min(calc(100dvh - var(--chrome)),calc((100vw - 24px) / var(--page-ratio)),780px)}
  .controls{grid-template-columns:minmax(0,1fr);gap:2px}
  .hint,.route-name{display:none}
  .route{gap:4px}
  .controls .route button{gap:6px;padding:8px 0 4px}
  .route-num{font-size:9px}
  .pager{justify-self:stretch;justify-content:space-between}
  #previous,#next{display:grid;place-items:center;width:48px;height:42px;padding:0;border:0;border-radius:0;background:none;color:var(--ink-2)}
  #previous svg,#next svg{width:30px;height:10px}
  #previous:disabled,#next:disabled{opacity:.15}
  .guide{place-items:start stretch;padding:16px}
  .guide-list button{grid-template-columns:44px minmax(0,1fr);grid-template-areas:"num zh" "num en";column-gap:14px;padding:16px 4px}
  .g-meta{display:none}
  .g-zh{font-size:24px}
  .room.guide-open .guide{-webkit-backdrop-filter:none;backdrop-filter:none;background:rgb(241 239 234 / 98%)}
}
/* The arc (phones, and any screen too short for the full ring): prints above, the title below. */
.entrance[data-mode="arc"] .entrance-copy{top:auto;bottom:calc(max(24px,env(safe-area-inset-bottom)) + 40px);transform:translateX(-50%)}
.room[data-phase="entering"] .entrance[data-mode="arc"] .entrance-copy{transform:translate(-50%,-20px)}
.entrance[data-mode="arc"] .name{font-size:clamp(52px,17vw,84px)}
.entrance[data-mode="arc"] .rule{margin:18px 0 20px}
.entrance[data-mode="arc"] .enter{justify-content:center;min-width:min(320px,calc(100vw - 52px))}
.entrance[data-mode="arc"] .ring-caption{left:0;right:0;bottom:auto;top:var(--caption-top,50%);width:max-content;margin:0 auto;text-align:center}
.entrance[data-mode="arc"] .entrance-foot{justify-content:center;font-size:10px;letter-spacing:.18em}
.entrance[data-mode="arc"] .ef-count{display:none}
@media (max-height:620px){
  .entrance[data-mode="arc"] .kicker,.entrance[data-mode="arc"] .subtitle,.entrance[data-mode="arc"] .rule,.entrance[data-mode="arc"] .entrance-foot,.entrance[data-mode="arc"] .ring-caption{display:none}
  .entrance[data-mode="arc"] .name{font-size:44px}
  .entrance[data-mode="arc"] .enter{margin-top:12px}
}
@media (prefers-reduced-motion:reduce){
  .room *,.room *::before,.room *::after{animation:none!important}
}
