@import url('https://fonts.googleapis.com/css2?family=Noto+Serif+TC:wght@400;600;800&display=swap');
:root{color-scheme:dark;--gold:#e8b84a;--paper:#f2e6cf;--red:#9b3138;--ink:#131921}*{box-sizing:border-box}body{margin:0;background:var(--ink);color:var(--paper);font-family:system-ui,-apple-system,sans-serif}button,a{-webkit-tap-highlight-color:transparent}button{font:inherit;color:inherit;cursor:pointer;border:1px solid #e8b84a44;background:#171923b8;border-radius:6px;padding:11px 18px;transition:.2s}button:hover:not(:disabled){background:#6b3435;border-color:var(--gold)}button:focus-visible,a:focus-visible{outline:3px solid var(--gold);outline-offset:4px}button:disabled{opacity:.45;cursor:not-allowed}a{color:var(--gold)}#app{position:relative;min-height:100svh;overflow:hidden}#scene{position:absolute;inset:0;min-height:100%;background:#26313c url('assets/apartment.webp') center/cover no-repeat;transition:filter 1.2s}#scene.day{filter:sepia(.25) brightness(1.15)}#scene.memory{filter:sepia(.65)}#scene.shop{background-color:#3f3026}#scene.temple{background:linear-gradient(155deg,#a8b6b7,#786953 55%,#292a31)}#scene.dark{background:#0a0c12}#scene .shade{position:absolute;inset:0;background:linear-gradient(90deg,#11131de8 0%,#16182275 42%,#14192110 75%),linear-gradient(0deg,#0f121be8,transparent 80%)}#portrait{position:absolute;right:6%;bottom:8%;height:78%;max-width:55%;object-fit:contain;object-position:bottom;filter:drop-shadow(0 0 40px #eab94b33);transition:opacity .45s}#portrait[src=""]{display:none}.grain{position:absolute;inset:0;background:radial-gradient(ellipse at 75% 20%,#e7b44c13,transparent 40%);pointer-events:none}header{position:relative;z-index:3;display:flex;align-items:center;gap:16px;padding:24px 4vw;border-bottom:1px solid #dfbd7620;background:#10131b40}#brand{font-family:'Noto Serif TC',serif;font-weight:800;font-size:20px;letter-spacing:.15em;text-decoration:none;color:var(--paper)}#chapter{flex:1;font-size:12px;letter-spacing:.12em;color:#d6c5a6}header button{padding:8px 14px;font-size:13px}#landing{position:relative;width:min(650px,90%);padding:6vh 0 3vh 8vw}.eyebrow{font-size:12px;color:var(--gold);letter-spacing:.35em}h1{font-family:'Noto Serif TC',serif;font-size:clamp(60px,7.5vw,112px);line-height:1.16;letter-spacing:.13em;margin:24px 0;color:#efc675;font-weight:600;text-shadow:0 6px 30px #0006}h1 span{padding-left:.9em}.subtitle{font:14px 'Noto Serif TC',serif;letter-spacing:.1em}.tear{height:1px;background:linear-gradient(90deg,var(--gold),transparent);width:240px;margin:25px 0}.intro{line-height:1.9;color:#e2d8c4;font:17px/1.9 'Noto Serif TC',serif}.primary{display:block;background:#9b3138;border-color:#bb6566;padding:16px 28px;margin:25px 0 10px;min-width:260px;text-align:left}.primary b{float:right;color:var(--gold)}.notice{font-size:11px;line-height:1.8;color:#c4b9a6;margin-top:24px}.textbtn{border:0;background:transparent;color:var(--gold);padding-left:0}#play{position:relative;padding-top:38vh;min-height:calc(100svh - 85px);display:flex;flex-direction:column;justify-content:flex-end}#play[hidden],#landing[hidden]{display:none}#dialogue{margin:0 5vw;padding:22px 32px 20px;background:linear-gradient(110deg,#101722f5,#1d202be8);border:1px solid #c1a46a66;border-top:2px solid #e8b84a88;border-radius:4px;box-shadow:0 12px 80px #0007;min-height:200px;position:relative}#speaker{color:var(--gold);font:600 18px 'Noto Serif TC',serif;letter-spacing:.2em;padding-bottom:5px}#text{font:clamp(18px,1.6vw,23px)/1.9 'Noto Serif TC',serif;white-space:pre-line;max-width:1100px;margin:10px 0 12px;min-height:2em}#next{display:block;margin-left:auto;background:transparent;border:none;color:var(--gold)}#choices{display:grid;gap:9px;margin-top:18px}#choices button{text-align:left;background:#41343866;border-color:#c1a46a66;padding:14px 18px;line-height:1.5}footer{display:flex;gap:12px;padding:15px 5vw 24px;align-items:center;color:#bcbaa9;font-size:12px}footer span{flex:1}footer button{font-size:12px;padding:8px 12px;background:#10131b99}#feedback{position:absolute;top:23vh;left:5vw;color:#f4d495;font:15px 'Noto Serif TC',serif;text-shadow:0 2px 5px black}dialog{background:#1b2029;color:var(--paper);border:1px solid #c6a36a;max-width:680px;width:calc(100% - 32px);max-height:85svh;padding:34px;border-radius:8px;box-shadow:0 20px 80px #0008}dialog::backdrop{background:#080c12c9;backdrop-filter:blur(4px)}#close{position:sticky;float:right;top:0;font-size:24px;padding:0 10px}dialog h2{font:26px 'Noto Serif TC',serif;color:var(--gold)}dialog p{line-height:1.9}dialog li{padding:12px 0;line-height:1.8}dialog .torn{color:#a39a88;border-bottom:2px dashed #a39a88}dialog small{color:#b4b0a7;line-height:1.7;display:block}.reading{padding:18px 0;border-top:1px solid #b59a6b44}.reading a{font-size:18px;text-decoration:none}.reading p{margin:10px 0;font-size:14px}#toast{position:fixed;bottom:30px;left:50%;transform:translateX(-50%);background:#ece0c4;color:#222;padding:12px 22px;border-radius:6px;z-index:10;opacity:0;pointer-events:none;transition:opacity .3s}.ending-title{font:30px 'Noto Serif TC',serif;color:var(--gold)}@media(max-width:600px){header{padding:16px;gap:8px;flex-wrap:wrap}#brand{font-size:17px}#chapter{order:4;flex-basis:100%;font-size:10px}header button{padding:7px 10px}#sound{margin-left:auto}#landing{padding:6vh 0 24px 7vw}h1{font-size:65px}#scene .shade{background:linear-gradient(90deg,#11131de0,#11131d55),linear-gradient(0deg,#11131df9,transparent 95%)}#portrait{height:54%;max-width:90%;right:-5%;bottom:30%;opacity:.9}#play{padding-top:30vh;min-height:calc(100svh - 102px)}#dialogue{margin:0 12px;padding:18px 20px}#text{font-size:18px;line-height:1.85}footer{gap:7px;flex-wrap:wrap;padding:13px 14px 22px}footer span{flex-basis:100%;font-size:10px}dialog{padding:24px}#feedback{top:20vh;left:20px;font-size:13px}}@media(prefers-reduced-motion:reduce){*{transition:none!important}}

#portrait{width:29.25vh;background:url(assets/characters.webp) 0 0/400% 100% no-repeat;max-width:45%;height:78vh;bottom:6%;right:13%}#portrait[data-person="jin"]{background-position:0% 0}#portrait[data-person="lin"]{background-position:33.33% 0}#portrait[data-person="grandma"]{background-position:66.66% 0}#portrait[data-person="song"]{background-position:100% 0}#portrait[hidden]{display:none}@media(max-width:600px){#portrait{height:54vh;width:20.25vh;right:8%;bottom:33%}}
#scene.day,#scene.shop,#scene.memory,#scene.temple{background-image:url(assets/scenes.webp);background-size:200% 200%;filter:none}#scene.day{background-position:0 0}#scene.shop{background-position:100% 0}#scene.memory{background-position:0 100%}#scene.temple{background-position:100% 100%}

[hidden]{display:none!important}
/* v2: two-person stage, the dialogue box follows the active speaker. */
#actors{position:absolute;inset:0;overflow:hidden;pointer-events:none}.actor{position:absolute;bottom:12%;height:76vh;width:28.5vh;max-width:35%;transition:opacity .5s,filter .5s,translate .7s;filter:brightness(.65) saturate(.7);opacity:.76;z-index:1}.actor.left{left:12%}.actor.right{right:12%}.actor.active{filter:brightness(1) drop-shadow(0 0 22px #e8b84a33);opacity:1;z-index:2}.figure{height:100%;width:100%;background:url(assets/characters.webp) 0 0/400% 100% no-repeat;transform-origin:50% 85%}.actor[data-person="jin"] .figure{background-position:0 0}.actor[data-person="lin"] .figure{background-position:33.33% 0}.actor[data-person="grandma"] .figure{background-position:66.66% 0}.actor[data-person="song"] .figure{background-position:100% 0}.actorName{position:absolute;bottom:12%;left:50%;transform:translateX(-50%);padding:5px 14px;background:#11131bc9;border:1px solid #b99b6666;font-size:12px;white-space:nowrap;opacity:0;transition:opacity .3s}.actor.active .actorName{opacity:1}.actor[data-person="jin"]{height:63vh;width:23.625vh}.actor.nod .figure{animation:nod 1s ease-in-out}.actor.step .figure{animation:step 1.5s ease-out}.actor.reach .figure{animation:reach 1.4s ease-in-out}.actor.look .figure{animation:look 1.4s ease-in-out}.actor.sad .figure{animation:sad 1.6s ease-out forwards}.actor.surprise .figure{animation:surprise .8s ease-out}@keyframes nod{50%{transform:translateY(6px) rotate(1deg)}}@keyframes step{0%{transform:translateX(20px);opacity:.2}100%{transform:translateX(0);opacity:1}}@keyframes reach{50%{transform:translateX(-12px) rotate(-1deg)}}@keyframes look{50%{transform:rotate(-1.2deg)}}@keyframes sad{100%{transform:translateY(5px) rotate(-.7deg)}}@keyframes surprise{45%{transform:translateY(-7px)}}
#dialogue{margin:0 auto;width:88%;max-width:1200px;border-radius:12px;backdrop-filter:blur(8px)}#dialogue::before{content:'';position:absolute;top:-12px;left:10%;width:20px;height:20px;background:#171d28;border-top:1px solid #c1a46a;border-left:1px solid #c1a46a;transform:rotate(45deg)}#dialogue[data-side="right"]::before{left:auto;right:10%}#dialogue[data-side="none"]::before{display:none}#dialogue[data-side="right"] #speaker{text-align:right}#dialogue[data-side="left"] #speaker{text-align:left}#dialogue[data-side="none"] #speaker{color:#bcb6aa;font-size:14px}#play{padding-top:43vh}#text{font-size:clamp(18px,1.65vw,22px);max-width:none}#cg{position:absolute;inset:0;background-position:center;background-size:cover;z-index:2}#cg::after{content:'';position:absolute;inset:0;background:linear-gradient(0deg,#11131beb,transparent 65%)}header{gap:10px}header button{font-size:12px;padding:7px 10px}#chapter{min-width:150px}.voice-note{color:#bbb;font-size:12px}.range-setting{display:flex;align-items:center;gap:15px;margin:15px 0}.range-setting input{width:100%}@media(max-width:600px){header{gap:6px;padding:12px}.actor{height:52vh;width:19.5vh;bottom:31%;max-width:47%}.actor.left{left:0}.actor.right{right:0}.actor[data-person="jin"]{height:43vh;width:16.125vh;right:4%}#play{padding-top:33vh}#dialogue{width:calc(100% - 24px);padding:16px 18px}#text{font-size:18px;line-height:1.8}#speaker{font-size:17px}footer{padding:12px;gap:6px}footer button{padding:8px 10px;font-size:11px}header #chapter{order:4;flex-basis:100%}header #brand{flex:1}header #sound{margin-left:0}header #voice,header #music{padding:7px 8px}header #menu{padding:7px 8px}#feedback{top:24vh}.actorName{bottom:20%}#landing{padding-top:3vh}}@media(prefers-reduced-motion:reduce){.figure{animation:none!important}}

#scene{z-index:0}#landing,#play{z-index:2}#panel{z-index:10}

.actor[data-person="young"] .figure{background-image:url(assets/young-yue.webp);background-size:contain;background-position:center bottom}.actor[data-person="young"]{height:65vh;width:28vh}@media(max-width:600px){.actor[data-person="young"]{height:43vh;width:20vh}}
@media(max-width:600px){#cg{background-size:100% auto;background-repeat:no-repeat;background-position:center 23%;background-color:#211d24}#cg::after{background:linear-gradient(0deg,#11131bff 0%,#11131b99 28%,transparent 65%)}}
/* V3: photographs are recollections, not a second pair of stage portraits. */
#speaker:empty{display:none}
#cg[data-kind="childhood"]{background-size:contain;background-position:center 20%;background-repeat:no-repeat;background-color:#211b18}
#scene:has(#cg:not([hidden])) #actors{visibility:hidden}
/* V4: a stable reading panel and dedicated, fixed-size continuation row. */
body:has(#play:not([hidden])) #app{height:100svh;min-height:0;display:flex;flex-direction:column}
body:has(#play:not([hidden])) header{flex:0 0 auto}
#play{flex:1 1 auto;min-height:0;height:auto;padding-top:0;justify-content:flex-end;overflow:hidden}
#dialogue{flex:0 0 auto;height:clamp(248px,34svh,350px);min-height:0;display:flex;flex-direction:column;padding:20px 30px 18px;overflow:visible}
#speaker{flex:0 0 auto}
#text{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;margin:8px 0 10px;padding-right:8px;scrollbar-width:thin}
#choices:empty{display:none}
#choices:not(:empty){flex:1 1 auto;min-height:0;overflow-y:auto;margin:8px 0 0;overscroll-behavior:contain}
#dialogue:has(#choices button) #text{flex:0 1 auto;max-height:30%}
#next{flex:0 0 48px;align-self:flex-end;width:112px;height:48px;min-height:48px;margin:0;padding:8px 14px;border:1px solid #e8b84a88;border-radius:9px}
#play footer{flex:0 0 auto}
@media(max-width:600px){#dialogue{height:clamp(300px,41svh,370px);padding:16px 18px 14px}#next{width:108px;height:46px;min-height:46px;flex-basis:46px}#play footer{padding-bottom:max(12px,env(safe-area-inset-bottom))}}
@media(max-height:560px){#dialogue{height:56svh;padding:10px 18px}#text{font-size:16px;line-height:1.6}#next{height:40px;min-height:40px;flex-basis:40px}#play footer{padding:7px 12px}header{padding-top:8px;padding-bottom:8px}}
#next{transition:background-color .2s,border-color .2s,color .2s}
/* V5 emotional artwork, preserving the original character identities. */
.actor[data-person="jin"][data-emotion="sad"] .figure{background-image:url(assets/jin-sad.webp);background-size:contain;background-position:center bottom;background-repeat:no-repeat}
.actor[data-person="jin"][data-emotion="reassured"] .figure{background-image:url(assets/jin-reassured.webp);background-size:contain;background-position:center bottom;background-repeat:no-repeat}
.actor[data-person="lin"][data-emotion="tearful"] .figure{background-image:url(assets/lin-tearful.webp);background-size:contain;background-position:center bottom;background-repeat:no-repeat}
.actor[data-emotion="fading"]{opacity:.42}
#slots button+button{margin-left:12px}
@media(max-width:600px){header #load{padding:7px 8px}#brand{font-size:15px}}
/* Keep faces and gestures above the fixed reading panel. */
#actors{--stage-height:calc(100svh - clamp(248px,34svh,350px) - 135px);--stage-bottom:calc(clamp(248px,34svh,350px) + 48px)}
#actors .actor{bottom:var(--stage-bottom);height:var(--stage-height);width:calc(var(--stage-height)*.375)}
#actors .actor[data-person="jin"]{height:calc(var(--stage-height)*.83);width:calc(var(--stage-height)*.31125)}
#actors .actor[data-person="young"]{height:calc(var(--stage-height)*.86);width:calc(var(--stage-height)*.40)}
@media(max-width:600px){#actors{--stage-height:calc(100svh - clamp(300px,41svh,370px) - 165px);--stage-bottom:calc(clamp(300px,41svh,370px) + 70px)}#actors .actor.left{left:8%}#actors .actor.right{right:8%}}
#actors .actor[data-person="jin"][data-emotion="sad"],#actors .actor[data-person="jin"][data-emotion="reassured"]{width:calc(var(--stage-height)*.55333)}
#actors .actor[data-person="lin"][data-emotion="tearful"]{width:calc(var(--stage-height)*.66667)}
#actors .actor.left{left:25%;transform:translateX(-50%)}
#actors .actor.right{right:25%;transform:translateX(50%)}
#cg{inset:82px 0 calc(clamp(248px,34svh,350px) + 82px);background-size:contain;background-position:center;background-repeat:no-repeat;background-color:#211d24}
#cg[data-kind="childhood"]{background-position:center}
#cg::after{background:linear-gradient(0deg,#11131b33,transparent 30%)}
@media(max-width:600px){#cg{inset:78px 0 calc(clamp(300px,41svh,370px) + 95px);background-size:contain;background-position:center}}
/* Weather is a complete scene assignment, shared with the audio layer. */
#scene.night[data-weather="none"]{background-image:url(assets/apartment-dry.webp);background-size:cover;background-position:center}
#scene.night[data-weather="rain"]{background-image:url(assets/apartment.webp);background-size:cover;background-position:center}
#scene.memory[data-weather="none"]{background-image:url(assets/memory-dry.webp);background-size:cover;background-position:center}
#scene.memory[data-weather="rain"]{background-image:url(assets/scenes.webp);background-size:200% 200%;background-position:0 100%}
/* Larger reading text; the fixed panel keeps its next button stable. */
#text{font-size:clamp(23px,2vw,28px);line-height:1.85;letter-spacing:.035em;touch-action:pan-y}
#speaker{font-size:21px}
#choices button{font-size:19px;line-height:1.6}
@media(max-width:600px){#text{font-size:22px;line-height:1.8}#speaker{font-size:20px}#choices button{font-size:18px}}
@media(max-height:560px){#text{font-size:20px;line-height:1.65}}
/* Choice scenes grow to fit their buttons instead of hiding them in a fixed box. */
#dialogue:has(#choices button){height:auto;max-height:calc(100svh - 155px);flex:0 1 auto}
#dialogue:has(#choices button) #text{flex:0 1 auto;max-height:24svh;margin-bottom:8px;font-size:23px;line-height:1.65}
#choices:not(:empty){flex:0 1 auto;grid-auto-rows:min-content;align-content:start;gap:8px;overflow-y:auto}
#choices button{min-height:48px;padding:11px 15px;font-size:18px;line-height:1.5}
@media(min-width:760px){#choices:has(button:nth-child(3)){grid-template-columns:1fr 1fr}}
@media(max-width:600px){#dialogue:has(#choices button){max-height:calc(100svh - 170px);padding:14px 16px}#dialogue:has(#choices button) #text{font-size:21px;line-height:1.65;max-height:22svh}#choices button{font-size:18px;padding:10px 13px}}
@media(max-height:560px){#dialogue:has(#choices button){max-height:calc(100svh - 115px);padding:10px 16px}#dialogue:has(#choices button) #text{font-size:20px;max-height:20svh}#choices button{font-size:17px;min-height:44px;padding:8px 12px}}

/* Portrait close-ups leave the reading controls in front of the stage. */
@media(max-width:600px) and (orientation:portrait){
  #actors .actor{top:104px;bottom:auto;height:60svh;width:22.5svh;max-width:46vw;opacity:.85}
  #actors .actor.left{left:26%;right:auto;transform:translateX(-50%)}
  #actors .actor.right{right:26%;left:auto;transform:translateX(50%)}
  #actors .actor[data-person="jin"]{height:50svh;width:26.75svh}
  #actors .actor[data-person="jin"] .figure{background-size:400% 142%;background-position:0 100%}
  #actors .actor[data-person="young"]{height:52svh;width:34.67svh}
  #actors .actor[data-person="jin"][data-emotion="sad"] .figure,
  #actors .actor[data-person="jin"][data-emotion="reassured"] .figure,
  #actors .actor[data-person="lin"][data-emotion="tearful"] .figure{background-size:contain;background-position:center top}
  #actors .actor.active,
  #actors:has(.actor.right[hidden]) .actor.left,
  #actors:has(.actor.left[hidden]) .actor.right{left:50%;right:auto;transform:translateX(-50%);height:72svh;width:27svh;max-width:none;opacity:1}
  #actors .actor.active[data-person="jin"]{height:60svh;width:32.1svh}
  #actors .actor.active[data-person="young"]{height:62svh;width:41.33svh}
  #actors .actor.active[data-person="jin"][data-emotion="sad"],
  #actors .actor.active[data-person="jin"][data-emotion="reassured"]{width:40svh}
  #actors .actor.active[data-person="lin"][data-emotion="tearful"]{width:48svh}
  #actors:has(.actor.active:not([hidden])) .actor:not(.active){visibility:hidden;opacity:0}
  #actors .actorName{display:none}
  #dialogue::before{display:none}
  #dialogue[data-side] #speaker{text-align:left}
}
@media(max-width:600px) and (orientation:portrait) and (max-height:700px){
  #dialogue{height:clamp(228px,40svh,280px)}
  #cg{inset:100px 0 calc(clamp(228px,40svh,280px) + 76px)}
  #actors .actor{top:96px}
}
