/* ═══════════════════════════════════════════════════════════════
   cinema.css — 영화 연출 (theme.css 뒤에 불러온다). 클래스 접두어: cn-
   transform·opacity만 움직인다. 필터는 정지 상태로만 쓴다.
   ═══════════════════════════════════════════════════════════════ */

/* ───────── 필름 질감: 그레인 + 비네트 ───────── */
.cn-film{position:fixed;inset:0;z-index:90;pointer-events:none;display:none;overflow:hidden;contain:strict}
html.cn-film-on body.vn-on .cn-film,
html.cn-film-on body:has(#app.titlepage) .cn-film,
html.cn-film-on body:has(#app.homepage) .cn-film{display:block}
body.in-room .cn-film{display:none!important}
.cn-film::before{content:"";position:absolute;inset:0;background:radial-gradient(ellipse 125% 95% at 50% 45%,transparent 60%,rgba(0,0,0,.38) 100%)}
body:has(#app.homepage) .cn-film::before{display:none}
.cn-film::after{content:"";position:absolute;inset:-64px;opacity:.07;will-change:transform;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1.6 -0.55'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E") 0 0/180px 180px repeat;
  animation:cnGrain .8s steps(1,end) infinite}
@keyframes cnGrain{0%{transform:translate(0,0)}16%{transform:translate(-23px,14px)}33%{transform:translate(19px,-27px)}50%{transform:translate(-35px,-9px)}66%{transform:translate(29px,31px)}83%{transform:translate(-11px,-36px)}}
:root.still .cn-film::after{animation:none}
:root.still-mq-off{.cn-film::after{animation:none}}

/* 시퀀스가 도는 동안 아래 화면의 등장 애니메이션을 멈춰 두었다가, 막이 걷힐 때 시작한다 */
#app.cn-hold,#app.cn-hold *{animation-play-state:paused!important}

/* ───────── 공통 시퀀스 막(챕터 오프닝·오프닝·엔드 크레디트) ───────── */
.cn-ov{position:fixed;inset:0;z-index:85;display:flex;align-items:center;justify-content:center;overflow:hidden;background:#000;color:#F2F0EC;
  cursor:pointer;-webkit-tap-highlight-color:transparent;user-select:none;-webkit-user-select:none}
.cn-ov.cn-end{animation:cnOvIn .5s ease-out both}
.cn-ov.cn-out{pointer-events:none;animation:cnOvOut .58s cubic-bezier(.4,0,.2,1) forwards}
@keyframes cnOvIn{from{opacity:0}}
@keyframes cnOvOut{to{opacity:0}}
.cn-plate{position:absolute;inset:0;background:center 30%/cover no-repeat;opacity:.42;will-change:transform,opacity;animation:cnPlate 3.4s cubic-bezier(.2,.6,.2,1) both}
.cn-plate::after{content:"";position:absolute;inset:0;background:radial-gradient(ellipse at 50% 50%,rgba(0,0,0,.25),rgba(0,0,0,.85) 80%),linear-gradient(180deg,rgba(0,0,0,.4),transparent 30%,transparent 70%,rgba(0,0,0,.6))}
.cn-plate.slow{animation-duration:12s;opacity:.3}
@keyframes cnPlate{from{opacity:0;transform:scale(1.12)}to{transform:scale(1.03)}}
/* 레터박스 */
.cn-bar{position:absolute;left:0;right:0;z-index:3;height:11vh;background:#000;transform:scaleY(0);animation:cnBar .7s cubic-bezier(.7,0,.2,1) .05s forwards}
.cn-bar.t{top:0;transform-origin:top;box-shadow:0 1px 0 rgba(233,185,73,.16)}
.cn-bar.b{bottom:0;transform-origin:bottom;box-shadow:0 -1px 0 rgba(233,185,73,.16)}
@keyframes cnBar{to{transform:scaleY(1)}}
.cn-skip{position:absolute;z-index:4;right:16px;bottom:calc(env(safe-area-inset-bottom,0px) + 3.5vh);font-family:var(--z-mono);font-size:11px;letter-spacing:.12em;color:rgba(242,240,236,.42);opacity:0;animation:cnFade .6s .9s forwards}
/* 글자 */
.cn-in{position:relative;z-index:2;text-align:center;padding:0 24px;max-width:900px;will-change:transform}
.cn-out .cn-in,.cn-out .cn-roll{animation:cnLift .58s cubic-bezier(.4,0,.2,1) forwards}
@keyframes cnLift{to{transform:translateY(-14px)}}
.cn-credit{margin-bottom:18px;font-family:var(--z-mono);font-size:11px;letter-spacing:.34em;padding-left:.34em;color:rgba(242,240,236,.55);animation:cnFade 1s .15s both}
.cn-kick{margin-bottom:14px;font-family:var(--z-mono);font-size:12px;font-weight:500;letter-spacing:.44em;padding-left:.44em;color:var(--z-amber,#E9B949);animation:cnTrack 1.5s .3s cubic-bezier(.2,.7,.2,1) both}
@keyframes cnTrack{from{opacity:0;transform:scaleX(1.3)}}
@keyframes cnFade{from{opacity:0}to{opacity:1}}
.cn-ttl{margin:0;font-family:var(--z-sans);font-weight:800;font-size:clamp(34px,9.5vw,66px);line-height:1.12;letter-spacing:-.045em;color:#fff;word-break:keep-all;text-wrap:balance;text-shadow:0 2px 30px rgba(0,0,0,.6)}
.cn-ttl.big{font-size:clamp(46px,14vw,96px)}
.cn-w{display:inline-block;white-space:nowrap}
.cn-ttl .cn-w>span{display:inline-block;opacity:0;animation:cnChar .9s calc(.5s + var(--i)*55ms) cubic-bezier(.2,.7,.2,1) both}
@keyframes cnChar{from{opacity:0;transform:translateY(.28em)}to{opacity:1}}
.cn-rule{display:block;width:120px;height:1px;margin:22px auto 0;background:linear-gradient(90deg,transparent,var(--z-amber,#E9B949),transparent);transform:scaleX(0);animation:cnRule 1.1s 1s cubic-bezier(.2,.7,.2,1) forwards}
@keyframes cnRule{to{transform:scaleX(1)}}
.cn-open .cn-ttl .cn-w>span{animation-delay:calc(.25s + var(--i)*60ms)}
.cn-open .cn-rule{animation-delay:.6s}
.cn-open .cn-kick{animation-delay:.1s}

/* ───────── 장소·시각 자막(장면 첫 줄): 영화 자막처럼 ───────── */
.vn-box.k-cap{background:none;border-color:transparent;box-shadow:none;backdrop-filter:none;-webkit-backdrop-filter:none;text-align:left}
.vn-box.k-cap::before{content:"";display:block;width:26px;height:2px;margin:0 0 12px;background:var(--z-amber,#E9B949)}
.vn-box.k-cap .vn-text.cap{text-align:left;padding-top:0;font-family:var(--z-mono);font-size:14.5px;font-weight:500;letter-spacing:.1em;line-height:1.7;color:#F3E6C6;
  text-shadow:0 1px 2px rgba(0,0,0,.9),0 0 18px rgba(0,0,0,.8)}
.vn-box.k-cap:not(.ready) .vn-text.cap::after{content:"";display:inline-block;width:.5em;height:1em;margin-left:3px;vertical-align:-.12em;background:currentColor;opacity:.8}
.vn-box.k-cap .vn-prog{opacity:.5}
@media(min-width:900px){.vn-box.k-cap .vn-text.cap{font-size:16px}}

/* ───────── 장면 전환 컷(새 그림이 들어올 때만) ───────── */
.vn.cn-cut .vn-img.in{animation:none}
/* 페이드 투 블랙: 검은 막이 걷히며 그림이 살짝 자리를 잡는다 */
.vn.cn-k-fade .vn-img.in{animation:cnImgSettle 1.4s cubic-bezier(.2,.6,.2,1) both}
@keyframes cnImgSettle{from{transform:scale(1.08)}}
.cn-black{position:absolute;inset:0;z-index:1;pointer-events:none;background:#000;will-change:opacity;animation:cnOut .95s .12s ease-out both}
/* 크로스 디졸브: 앞 그림이 새 그림 위에서 녹아 사라진다 */
.cn-ghost{position:absolute;inset:0;z-index:1;pointer-events:none;will-change:opacity;animation:cnOut 1.15s ease-in-out forwards}
.vn.cn-k-memory .cn-ghost{animation-duration:2.6s}
.cn-bloom{position:absolute;inset:0;z-index:1;pointer-events:none;background:radial-gradient(ellipse at 50% 42%,rgba(255,236,200,.32),rgba(255,236,200,0) 70%);will-change:opacity;animation:cnOut 2.8s ease-out both}
/* 플래시 컷: 한 프레임 섬광 + 짧은 펀치 인 */
.vn.cn-k-flash .vn-img.in,.vn.cn-k-cut .vn-img.in{animation:cnImgPunch .6s cubic-bezier(.15,.8,.2,1) both}
@keyframes cnImgPunch{from{transform:scale(1.1)}}
.cn-flash{position:absolute;inset:0;z-index:1;pointer-events:none;background:#fff;will-change:opacity;animation:cnFlashA .45s ease-out both}
.cn-flash.ng{background:#ffd9d2}
@keyframes cnFlashA{0%{opacity:.9}100%{opacity:0}}
@keyframes cnOut{from{opacity:1}to{opacity:0}}

/* ───────── 판정 결과: 정지 화면 + 슬로 모션 ───────── */
.cn-verdict{position:absolute;inset:0;z-index:3;pointer-events:none;overflow:hidden;animation:cnVerdict 2.2s linear forwards}
@keyframes cnVerdict{0%,74%{opacity:1}100%{opacity:0}}
.cn-freeze{position:absolute;inset:0;display:flex;justify-content:center;will-change:transform;transform-origin:50% 42%;animation:cnSlow 2.2s cubic-bezier(.1,.5,.3,1) both}
@keyframes cnSlow{from{transform:scale(1)}to{transform:scale(1.07)}}
.cn-win .cn-freeze{filter:sepia(.45) saturate(1.25) contrast(1.15) brightness(.9)}
.cn-lose .cn-freeze{filter:grayscale(1) contrast(1.3) brightness(.72)}
.cn-spl .cn-freeze{filter:grayscale(.7) contrast(1.15) brightness(.85)}
.cn-lose .cn-freeze::after{content:"";position:absolute;inset:0;background:radial-gradient(ellipse at 50% 45%,transparent 35%,rgba(140,20,14,.55))}
.cn-shutter{position:absolute;inset:0;background:#fff;opacity:0;animation:cnFlashA .3s ease-out both}
.cn-lose .cn-shutter{background:#b3160c;animation-duration:.4s}
.cn-vbar{position:absolute;left:0;right:0;height:9vh;background:#000;transform:scaleY(0);animation:cnBar .35s cubic-bezier(.7,0,.2,1) forwards}
.cn-vbar.t{top:0;transform-origin:top}.cn-vbar.b{bottom:0;transform-origin:bottom}
.cn-v-in{position:absolute;left:0;right:0;top:34%;text-align:center;padding:0 20px;animation:cnSlowText 2.2s cubic-bezier(.1,.6,.3,1) both}
@keyframes cnSlowText{from{transform:scale(1.1)}to{transform:scale(1)}}
.cn-v-k{display:block;margin-bottom:10px;font-family:var(--z-mono);font-size:12px;font-weight:600;letter-spacing:.5em;padding-left:.5em;color:var(--z-amber,#E9B949);animation:cnFade .5s .1s both}
.cn-lose .cn-v-k{color:#FF8A7A}.cn-spl .cn-v-k{color:#9CC8DC}
.cn-v-t{display:block;font-family:var(--z-sans);font-weight:800;font-size:clamp(28px,8vw,52px);line-height:1.15;letter-spacing:-.03em;color:#fff;word-break:keep-all;text-shadow:0 2px 24px rgba(0,0,0,.85)}
.cn-v-t .cn-w>span{display:inline-block;opacity:0;animation:cnChar .7s calc(.18s + var(--i)*70ms) cubic-bezier(.2,.7,.2,1) both}
.cn-verdict .cn-rule{animation-delay:.4s;width:90px;margin-top:16px}
.cn-lose .cn-rule{background:linear-gradient(90deg,transparent,#FF6B5C,transparent)}

/* ───────── 엔드 크레디트 ───────── */
.cn-end{align-items:flex-start}
.cn-roll{position:absolute;left:0;right:0;z-index:2;text-align:center;padding:0 24px;will-change:transform}
.cn-r-head{padding-bottom:12vh}
.cn-end .cn-kick{animation-delay:.2s}
.cn-end .cn-ttl{font-size:clamp(30px,8.5vw,58px)}
.cn-end .cn-ttl .cn-w>span{animation-delay:calc(.45s + var(--i)*70ms)}
.cn-end .cn-rule{animation-delay:1.2s}
.cn-r-sec{display:flex;flex-direction:column;align-items:center;gap:6px;margin:0 auto 9vh;opacity:0;animation:cnFade .8s 1.8s forwards}
.cn-r-sec span{font-family:var(--z-mono);font-size:11px;letter-spacing:.3em;padding-left:.3em;color:rgba(242,240,236,.5);margin-bottom:6px}
.cn-r-sec b{font-family:var(--z-sans);font-weight:600;font-size:19px;letter-spacing:-.01em;color:#F2F0EC}
.cn-r-end{padding:4vh 0;font-family:var(--z-sans);font-weight:800;font-size:clamp(26px,7vw,40px);letter-spacing:.3em;padding-left:.3em;color:#fff;opacity:0;animation:cnFade .8s 1.8s forwards}

:root.still-mq-off{.cn-ov,.cn-verdict,.cn-ghost,.cn-black,.cn-flash,.cn-bloom{display:none!important}}
