/* Chapter 05, In their words: testimonials as hanging scrolls (kakejiku) in front of an ink drawing.
   Each scroll hangs by a cord from a peg on the rail: top rod, two silk ribbons (fūtai), a silk mount around washi paper
   with the person's ink portrait, and a weighted roller at the bottom. --p is how far it's unrolled (0 to 1): the paper is
   clipped to it and the roller rides down with it, so one transition unrolls the whole thing. Without JS, or with reduced
   motion, --p stays 1 and the scrolls simply hang open. */
@property --p{syntax:'<number>';inherits:true;initial-value:1}
.vo{--wood:#3a2618;--wood-hi:#6b4a30;--brass:#c9963c}

/* behind the scrolls: an ink drawing that fades into the page, with a band of ink mist drifting slowly across it. The mist is a transparent image moved with translate only, so it
   stays cheap on phones. Night swaps in inverted drawings (pale ink on dark paper), made ahead of time, not filtered live. */
.vo-hall{--ink:url(../media/voices/ink-pines-1920.webp);--ink-s:url(../media/voices/ink-pines-960.webp);--ink-n:url(../media/voices/ink-pines-night-1920.webp);--ink-ns:url(../media/voices/ink-pines-night-960.webp);--ink-pos:50% 100%;
  position:relative;padding:0 clamp(16px,3vw,48px) clamp(44px,5.5vw,84px)}
/* no frame: the drawing bleeds past the scrolls (to the screen edge at most) and its edges dissolve into the page */
.vo-air{position:absolute;inset:-24px clamp(-140px,calc(50% - 50vw),0px) -64px;z-index:0;overflow:hidden;pointer-events:none;
  -webkit-mask:linear-gradient(to right,transparent,#000 15%,#000 85%,transparent),linear-gradient(transparent,#000 14%,#000 78%,transparent);-webkit-mask-composite:source-in;
  mask:linear-gradient(to right,transparent,#000 15%,#000 85%,transparent),linear-gradient(transparent,#000 14%,#000 78%,transparent);mask-composite:intersect}
.vo-ink{position:absolute;inset:0;background:var(--ink) var(--ink-pos)/cover no-repeat}
.vo-mist,.vo-air:after{position:absolute;left:-30%;width:160%;height:30%;background:url(../media/voices/ink-mist.webp) center/100% 100% no-repeat;opacity:.5;animation:vo-drift 52s ease-in-out infinite alternate}
.vo-mist{top:2%}
.vo-air:after{content:"";bottom:4%;opacity:.38;scale:-1 1;animation-duration:67s;animation-direction:alternate-reverse}
@keyframes vo-drift{from{translate:-6% 0}to{translate:6% 0}}
.vo-strip{position:relative;z-index:1}
.is-night .vo-ink{background-image:var(--ink-n)}
.is-night .vo-mist,.is-night .vo-air:after{background-image:url(../media/voices/ink-mist-night.webp)}
.vo-rv{display:none}
.vo-rv{position:absolute;z-index:2;width:7px;height:7px;border-radius:50%;background:radial-gradient(circle at 35% 35%,#ffe3a3,#c9963c 70%);box-shadow:0 0 0 1px rgba(0,0,0,.5)}
.vo-rv.tl{left:6px;top:6px}.vo-rv.tr{right:6px;top:6px}.vo-rv.bl{left:6px;bottom:6px}.vo-rv.br{right:6px;bottom:6px}

.vo-l{position:relative;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(20px,3vw,48px);max-width:1220px;margin:0 auto;padding:30px 0 0;list-style:none}
/* the rail: one wooden beam with brass end caps, every scroll's peg sits on it */
.vo-l:before{content:"";position:absolute;left:-14px;right:-14px;top:22px;height:9px;border-radius:5px;
  background:linear-gradient(to bottom,var(--wood-hi),var(--wood) 55%,#1c120b);box-shadow:0 2px 0 rgba(0,0,0,.35),inset 0 1px 0 rgba(255,255,255,.12)}
.vo-l:after{content:"";position:absolute;left:-22px;right:-22px;top:20px;height:13px;pointer-events:none;
  background:radial-gradient(circle at 6px 50%,#ffe3a3,var(--brass) 4px,#7a5a22 6px,transparent 6.5px) left/13px 13px no-repeat,radial-gradient(circle at 6px 50%,#ffe3a3,var(--brass) 4px,#7a5a22 6px,transparent 6.5px) right/13px 13px no-repeat}

/* one scroll */
.sc{--p:1;--H:600px;--silk:#6b6a65;position:relative;padding-top:58px;transform-origin:50% 0;
  transition:--p 1.2s cubic-bezier(.62,0,.22,1.05) calc(var(--d,0) * 1s)}   /* keep in step with UNROLL in voices.js */
.sc-cord{position:absolute;left:14%;right:14%;top:0;height:58px;pointer-events:none;
  background:linear-gradient(to top right,transparent calc(50% - 1px),#c9b48a calc(50% - .6px),#8d7550 calc(50% + .6px),transparent calc(50% + 1px)) left/50% 100% no-repeat,
             linear-gradient(to top left,transparent calc(50% - 1px),#c9b48a calc(50% - .6px),#8d7550 calc(50% + .6px),transparent calc(50% + 1px)) right/50% 100% no-repeat}
.sc-cord:before{content:"";position:absolute;left:50%;top:-4px;width:12px;height:12px;margin-left:-6px;border-radius:50%;background:radial-gradient(circle at 35% 35%,#fff0c4,#d9a54a 60%,#7a5a22);box-shadow:0 1px 2px rgba(0,0,0,.6)}
/* top rod, and the two ribbons that hang from it */
.sc-band{position:absolute;z-index:2;left:-5px;right:-5px;top:52px;height:9px;border-radius:2px;background:linear-gradient(to bottom,var(--wood-hi),var(--wood) 60%,#1c120b);box-shadow:0 2px 3px rgba(0,0,0,.45)}
.sc-band:before,.sc-band:after{content:"";position:absolute;top:9px;width:9px;height:calc(var(--p) * 58px);
  background:linear-gradient(to right,rgba(0,0,0,.18),transparent 30%,transparent 70%,rgba(0,0,0,.18)),color-mix(in srgb,var(--silk) 70%,#e9dcc0);box-shadow:0 1px 2px rgba(0,0,0,.25)}
.sc-band:before{left:28%}.sc-band:after{right:28%}

/* the silk mount: deeper at the top (heaven) than at the bottom (earth), like a real kakejiku */
.sc-body{position:relative;padding:52px 13px 34px;
  background:linear-gradient(to right,rgba(0,0,0,.22),transparent 10%,transparent 90%,rgba(0,0,0,.22)),url(../media/voices/brocade.webp) center/150px,var(--silk);background-blend-mode:normal,soft-light,normal;
  clip-path:inset(0 -8px calc((1 - var(--p)) * 100%) -8px);box-shadow:0 0 0 1px rgba(0,0,0,.25)}
.sc-paper{display:block;padding:12px 12px 14px;color:#1d1c19;background:#f3ecdc url(../media/washi.webp) center/cover;
  border-block:6px solid color-mix(in srgb,var(--silk) 55%,#d4ae5c);box-shadow:inset 0 0 0 1px rgba(65,48,27,.18)}
.sc-pic{position:relative;margin:0}
.sc-pic img{display:block;width:100%;height:auto;aspect-ratio:3/4;object-fit:cover;box-shadow:0 0 0 1px rgba(29,28,25,.18)}
/* the name runs down a paper label, as on the scrolls in a temple */
.sc-tag{position:absolute;left:8px;top:8px;margin:0;padding:10px 4px;writing-mode:vertical-rl;background:#fbf7ee;box-shadow:0 0 0 1px rgba(29,28,25,.55),2px 2px 0 rgba(29,28,25,.18)}
.sc-tag b{font:600 14px/1 var(--f-body,"Geist",system-ui,sans-serif);letter-spacing:.06em;color:#1d1c19}
.sc-q{margin:14px 2px 0;font:450 14.5px/1.5 var(--f-body);letter-spacing:-.005em;text-wrap:pretty}
.sc-q p{margin:0}
.sc-q p:before{content:"“";margin-right:2px;font:400 26px/0 "Bangers",sans-serif;color:var(--marker,#e8590c);vertical-align:-7px}
/* the position is the first thing you read after the name: an ink plate hung off the bottom of the portrait, the title in
   manga lettering and the company under it */
.sc-pos{position:absolute;right:-7px;bottom:-16px;z-index:1;display:grid;justify-items:end;max-width:calc(100% - 20px);margin:0;padding:7px 12px 8px 14px;
  background:#1d1c19;color:#f5f0e6;box-shadow:4px 4px 0 var(--marker,#e8590c);rotate:-2deg;text-align:right}
.sc-pos b{font:400 34px/.9 "Bangers",var(--f-body);letter-spacing:.05em;color:#fff;text-shadow:2px 2px 0 var(--marker,#e8590c)}
.sc-pos span{margin-top:4px;font:600 11.5px/1.25 var(--f-mono);letter-spacing:.09em;text-transform:uppercase;text-wrap:balance}
.sc-pic:has(.sc-pos) + .sc-q{margin-top:30px}
.sc-role{display:flex;align-items:center;justify-content:space-between;gap:10px;margin:14px 2px 0;padding-top:12px;border-top:1px dashed rgba(29,28,25,.25)}
.sc-src{color:#1d1c19;font-size:10.5px}   /* an .ink-link; the scroll paper is cream in both themes, so its ink stays dark */
.sc-hk{flex:none;position:relative;display:grid;place-items:center;width:32px;height:32px;border-radius:3px 2px 4px 2px;background:url(../media/seal-red.webp) center/cover;color:#fbefe6;font:700 12px/1 "Hiragino Mincho ProN","Yu Mincho",Georgia,serif;letter-spacing:.04em;rotate:-5deg}

/* the weighted roller: rides down with --p; while rolled it carries the whole scroll wound round it */
.sc-roll{position:absolute;z-index:3;left:-3px;right:-3px;top:58px;height:calc(10px + (1 - var(--p)) * 16px);border-radius:7px;
  transform:translateY(calc(var(--p) * (var(--H) - 12px) + 3px));
  background:linear-gradient(to bottom,rgba(255,255,255,.22),transparent 35%,rgba(0,0,0,.35)),url(../media/voices/brocade.webp) center/150px,var(--silk);background-blend-mode:normal,soft-light,normal;
  box-shadow:0 -14px 16px -12px rgba(0,0,0,calc((1 - var(--p)) * .9)),0 3px 4px rgba(0,0,0,.4)}
.sc-roll:before{content:"";position:absolute;left:-8px;right:-8px;bottom:-5px;height:9px;border-radius:5px;background:linear-gradient(to bottom,var(--wood-hi),var(--wood) 55%,#1c120b)}
.sc-roll i{position:absolute;bottom:-8px;width:13px;height:15px;border-radius:4px;background:radial-gradient(circle at 40% 35%,#8a6442,#3a2618 70%);box-shadow:inset 0 0 0 1px rgba(0,0,0,.35)}
.sc-roll i:first-child{left:-18px}.sc-roll i:last-child{right:-18px}

/* where the quote can be checked */

/* the seal stamps on as the scroll lands, leaving a few specks of red ink */
.sc.unstamped .sc-hk{opacity:0}
.sc.stamped .sc-hk{animation:sc-stamp .5s cubic-bezier(.2,1.5,.4,1)}
.sc.stamped .sc-hk:after{content:"";position:absolute;inset:-9px;pointer-events:none;opacity:.6;animation:sc-splat .55s ease-out;
  background:radial-gradient(circle at 8% 22%,#b3261e 1.6px,transparent 2.2px),radial-gradient(circle at 88% 10%,#b3261e 1.1px,transparent 1.6px),radial-gradient(circle at 96% 78%,#b3261e 2px,transparent 2.6px),radial-gradient(circle at 14% 92%,#b3261e 1px,transparent 1.5px),radial-gradient(circle at 60% 2%,#b3261e .9px,transparent 1.4px)}
@keyframes sc-stamp{0%{opacity:0;scale:2.3}55%{opacity:1;scale:.9}100%{scale:1}}
@keyframes sc-splat{0%{opacity:0;scale:.4}40%{opacity:.9}100%{opacity:.6;scale:1}}

/* the drawing blooms in like ink dropped on wet paper the first time you reach it, then the scrolls unroll */
.vo.ink-wait .vo-ink{-webkit-mask:url(../media/voices/ink-bloom.webp) 50% 45%/0% auto no-repeat;mask:url(../media/voices/ink-bloom.webp) 50% 45%/0% auto no-repeat}
.vo.inking .vo-ink{animation:vo-bloom 2.6s cubic-bezier(.55,.05,.3,1) forwards}
@keyframes vo-bloom{to{-webkit-mask-size:290% auto;mask-size:290% auto}}
.vo-mist,.vo-air:after{transition:opacity 1.6s .7s}
.vo.ink-wait:not(.inking) .vo-mist,.vo.ink-wait:not(.inking) .vo-air:after{opacity:0}

/* the crane's perch when motion is reduced (the crane itself lives in crane/crane.css) */
.vo-sky{position:absolute;inset:0;z-index:3;pointer-events:none}

/* nothing heavy loads until the section is about a screen away (voices.js drops .far) */
.vo.far .vo-ink,.vo.far .vo-mist,.vo.far .vo-air:after,.vo.far .sc-roll:after,.vo.far .sc-body,.vo.far .sc-roll{background-image:none}

/* a breath of smoke kicked up as the roller lands */
.sc-roll:after{content:"";position:absolute;left:-35%;right:-35%;top:-70px;height:120px;pointer-events:none;opacity:0;background:url(../media/voices/puff-ink.webp) center/100% 100% no-repeat}
.sc.landed .sc-roll:after{animation:sc-puff 2.4s cubic-bezier(.2,.6,.3,1)}
@keyframes sc-puff{0%{opacity:0;transform:translateY(34px) scale(.45,.3)}22%{opacity:.7}100%{opacity:0;transform:translateY(-22px) scale(1.25,1.1)}}

/* rolled up, and the swing once it lands */
.sc.rolled{--p:0;transition:none}
.sc.swing{animation:sc-swing 2.6s cubic-bezier(.3,.6,.4,1)}
@keyframes sc-swing{0%{rotate:0deg}14%{rotate:1.3deg}36%{rotate:-.9deg}58%{rotate:.5deg}78%{rotate:-.2deg}100%{rotate:0deg}}
.sc.sway{animation:sc-sway 1.6s ease-in-out}
@keyframes sc-sway{0%,100%{rotate:0deg}30%{rotate:.7deg}70%{rotate:-.45deg}}

/* the blank scroll: greyed, still waiting for a portrait */
.sc-next .sc-body{filter:grayscale(1)}
.sc-next .sc-tag b{color:#6b6a65}
.sc-q-next{font:500 21px/1.15 var(--f-hand,"Caveat",cursive);color:#45443f}

/* review marker: the owner must replace this before launch */

/* narrower screens: the scrolls become a strip you swipe in front of the wall, each unrolls as it slides in */
@media (max-width:1100px){
  .vo-hall{padding-inline:0}
  /* sideways only: with overflow-y left to auto the strip also scrolled ~40px up and down, so a vertical swipe that started
     on a scroll moved the strip before the page. The bottom padding (taken back with the margin) keeps the roller and its
     swing inside the strip instead of clipping them */
  .vo-strip{overflow-x:auto;overflow-y:hidden;padding-bottom:56px;margin-bottom:-56px;scroll-snap-type:x mandatory;overscroll-behavior-x:contain;touch-action:pan-x pan-y;scrollbar-width:none}
  .vo-strip::-webkit-scrollbar{display:none}
  /* the drawing is wider than the screen here; voices.js pans it as you swipe, so you walk from the left pines to the right */
  .vo-ink{right:auto;width:auto;aspect-ratio:16/9;background-image:var(--ink-s);background-size:100% 100%;will-change:transform}
  .is-night .vo-ink{background-image:var(--ink-ns)}
  /* the bloom would start off-screen in this wide drawing, so phones get a soft fade instead */
  .vo.ink-wait .vo-ink{-webkit-mask:none;mask:none;transition:opacity 1.4s ease-out}
  .vo.ink-wait:not(.inking) .vo-ink{opacity:0}
  .vo.inking .vo-ink{animation:none}
  .vo-air{-webkit-mask:linear-gradient(transparent,#000 10%,#000 80%,transparent);mask:linear-gradient(transparent,#000 10%,#000 80%,transparent)}
  .vo-l{grid-template-columns:repeat(4,clamp(240px,62vw,300px));width:max-content;max-width:none;padding:30px 36px 0}
  .vo-l:before{left:22px;right:22px}.vo-l:after{left:14px;right:14px}
  .sc{scroll-snap-align:center}
}
@media (prefers-reduced-motion:reduce){.sc{transition:none}.sc.swing,.sc.sway,.sc.landed .sc-roll:after,.vo-mist,.vo-air:after,.sc.stamped .sc-hk,.sc.stamped .sc-hk:after{animation:none}}
