  /* ════ chapter VICTORY (Quiet-Canvas skin): warm-gold celebration reusing modal_canvas + fx_light_burst.
     Same lavish composition as the reference (crown frame, gold stars, burst) tuned to the calm palette. ════ */
  #chapterWin { position: fixed; inset: 0; z-index: 70; display: none; flex-direction: column;
    align-items: center; justify-content: center; gap: 9px; padding: 18px 24px;
    background: linear-gradient(rgba(8,16,28,.18), rgba(6,14,26,.42)), url('../../assets/gallery/bg.webp') center / cover no-repeat; overflow: hidden; }
  #chapterWin.show { display: flex; animation: chwFade .5s ease-out both; }
  #chapterWin::before { content: none; }  /* damask now lives in the bg image */
  #chapterWin h2 { margin: 0; font-size: 0; color: transparent; z-index: 1;
    width: min(74vw, 330px); aspect-ratio: 700 / 142;
    background: url('../../assets/win/victory_text.webp') center / contain no-repeat;
    filter: drop-shadow(0 4px 6px rgba(60,20,5,.45)) drop-shadow(0 0 18px rgba(240,160,30,.4));
    animation: chwTitlePop .6s cubic-bezier(.2,1.4,.35,1) both; }
  #chapterWin .chwStars { display: flex; gap: 10px; z-index: 1; }
  #chapterWin .chwStars span { width: 56px; height: 56px; font-size: 0;
    background: url('../../assets/map/star_icon.webp') center / contain no-repeat;
    filter: grayscale(.9) brightness(.95) opacity(.5); }
  #chapterWin .chwStars span.on { filter: drop-shadow(0 2px 3px rgba(120,80,10,.45)) drop-shadow(0 0 12px rgba(246,200,60,.9));
    animation: chwStarPop .5s cubic-bezier(.2,1.6,.4,1) both; }
  #chapterWin .chwArtWrap { position: relative; width: 42vw; max-width: 172px; aspect-ratio: 421 / 432; display: flex; align-items: center; justify-content: center; z-index: 1; }
  /* soft energy halo behind the crystal frame (cyan-tinted) */
  #chapterWin .chwBurst { position: absolute; width: 220%; height: 220%; pointer-events: none;
    background: url('../../assets/win/light_burst.webp') center / contain no-repeat; opacity: .8;
    filter: hue-rotate(165deg) saturate(1.15) brightness(1.05); animation: chwBurstPulse 2.6s ease-in-out infinite; }
  /* crystal frame: always visible; the stained glass forms inside its hexagon on reveal */
  #chapterWin .artCell, #windowView .artCell { position: relative; width: 100%; aspect-ratio: 421 / 432; z-index: 1; --art-shift: 3%; }
  /* the artwork hexagon (glass + dark interior + flying shards + flash) sits inset 13%, nudged DOWN by
     --art-shift to register with frame.webp's window (its opening sits a hair below the cell's centre,
     so a centred hexagon left the bottom of the frame empty). One var tunes all four layers together. */
  /* crystal frame (frame.webp) + dark hexagon interior REMOVED (owner 2026-06-25): the artwork now shows as the
     full SQUARE picture (greyscale base + colour reveal), no crystal-shaped frame. */
  #chapterWin .artCell::before, #windowView .artCell::before,
  #chapterWin .artCell::after, #windowView .artCell::after { display: none; }
  /* reward UI stays hidden during the wind-up, then blooms in on reveal */
  #chapterWin .chwStars, #chapterWin .chwLabel, #chapterWin .chwReward, #chapterWin .chwStory, #chapterWin .chwBtns, #chapterWin .chwSeason, #chapterWin .chwCostume { opacity: 0; }
  /* reward UI blooms in only at SETTLE — i.e. AFTER the quiet admire beat (chw-settled added ~1.2s after
     chw-revealed), so the artwork gets its solo moment before stars/reward/buttons arrive. */
  #chapterWin.chw-settled .chwStars { animation: chwUiIn .5s ease-out .05s both; }
  #chapterWin.chw-settled .chwLabel { animation: chwUiIn .5s ease-out .18s both; }
  #chapterWin.chw-settled .chwStory { animation: chwUiIn .5s ease-out .24s both; }
  #chapterWin.chw-settled .chwReward { animation: chwUiIn .5s ease-out .30s both; }
  #chapterWin.chw-settled .chwBtns  { animation: chwUiIn .5s ease-out .38s both; }
  /* season finale (소프트런치): warm banner + Sha's promise, last to bloom — pure 여운 after the reward (§2.3) */
  #chapterWin.chw-settled .chwSeason { animation: chwUiIn .5s ease-out .46s both; }
  #chapterWin .chwSeason { display: none; flex-direction: column; align-items: center; gap: 5px; z-index: 1; width: min(86vw, 360px); }
  #chapterWin .chwSeason.on { display: flex; }
  #chapterWin .chwSeasonBanner {
    font-family: 'Jua', system-ui, sans-serif; font-weight: 400; font-size: clamp(16px, 4.6vw, 20px); letter-spacing: .3px;
    color: var(--gold); -webkit-text-stroke: 1.2px var(--gold-deep); paint-order: stroke fill;
    text-shadow: 0 2px 0 var(--gold-deep), 0 4px 7px rgba(60,34,4,.4);
  }
  #chapterWin .chwSeasonSha {
    max-width: 320px; text-align: center; color: rgba(255,250,240,.88); line-height: 1.45;
    font-size: clamp(12px, 3.3vw, 13.5px); font-weight: 700; text-shadow: 0 1px 3px rgba(0,0,0,.6);
  }
  /* costume nudge (lever ③): a soft 여운-phase chip — lighter than the primary Continue so it reads as an
     optional invitation, not a competing CTA. Fades in LAST (latest stagger) → never steals the artwork/reward. */
  #chapterWin.chw-settled .chwCostume { animation: chwUiIn .5s ease-out .54s both; }
  #chapterWin .chwCostume { display: none; flex-direction: column; align-items: center; gap: 7px; z-index: 1; width: min(86vw, 360px); }
  #chapterWin .chwCostume.on { display: flex; }
  #chapterWin .chwCostumeLine {
    max-width: 300px; text-align: center; color: rgba(255,248,235,.9); line-height: 1.4;
    font-size: clamp(12px, 3.2vw, 13px); font-weight: 800; text-shadow: 0 1px 3px rgba(0,0,0,.6);
  }
  #chapterWin .chwCostumeBtn {
    padding: 8px 20px 9px; border: 1.5px solid rgba(255,226,140,.55); border-radius: 999px; cursor: pointer;
    background: linear-gradient(180deg, rgba(120,86,170,.92), rgba(78,52,128,.95));
    color: #fff6e6; font-size: clamp(12.5px, 3.4vw, 14px); font-weight: 900; letter-spacing: .2px;
    text-shadow: 0 1px 2px rgba(0,0,0,.45); box-shadow: 0 3px 6px rgba(30,16,50,.4), inset 0 1px 0 rgba(255,255,255,.18);
  }
  #chapterWin .chwCostumeBtn:active { transform: translateY(1px) scale(.98); filter: brightness(.96); }
  /* wardrobe DISCOVERY (first time): loud — gold headline + NEW badge + a few button pulses. Still in the 여운
     phase (doesn't steal the artwork peak), but impossible to miss (report: too quiet → read as a bug). */
  #chapterWin .chwCostume.discovery .chwCostumeLine {
    color: var(--gold-pale); font-size: clamp(13.5px, 3.7vw, 15.5px); font-weight: 950;
    text-shadow: 0 1px 0 var(--gold-deep), 0 0 10px rgba(255,224,122,.7);
  }
  #chapterWin .chwCostumeNew {
    align-self: center; padding: 2px 10px 3px; border-radius: 999px; letter-spacing: .16em;
    background: linear-gradient(180deg, #ffd96a, #e0a83a); color: #5a3a08; font-size: 10px; font-weight: 950;
    box-shadow: 0 2px 5px rgba(80,50,8,.4), inset 0 1px 0 rgba(255,255,255,.5);
  }
  #chapterWin .chwCostume.discovery .chwCostumeBtn {
    border-color: rgba(255,236,160,.9);
    box-shadow: 0 3px 8px rgba(30,16,50,.45), 0 0 16px rgba(190,140,255,.55), inset 0 1px 0 rgba(255,255,255,.25);
    animation: costumeDiscoverPulse 1.5s ease-in-out 1.1s 3;
  }
  @keyframes costumeDiscoverPulse { 0%,100% { transform: scale(1); } 50% { transform: scale(1.06); } }
  html[data-motion="reduced"] { #chapterWin .chwCostume.discovery .chwCostumeBtn { animation: none; } }
  /* full SQUARE artwork (hexagon clip + frame removed, owner 2026-06-25). VICTORY: the greyscale picture fades in,
     then the collected COLOUR blooms into it. */
  #chapterWin .artGlass, #windowView .artGlass { position: absolute; inset: 0; z-index: 1; width: auto; height: auto; border-radius: 12px; opacity: 0; }
  #windowView .artGlass { opacity: 1; }   /* viewer shows the window immediately (no reveal wind-up) */
  #chapterWin.chw-revealed .artGlass { animation: chwArtIn .6s cubic-bezier(.2,.85,.25,1.2) both; }
  #chapterWin.chw-revealed .artColor { animation: chwColorBloom .9s ease-out .25s both; }   /* 흑백→컬러 차오름 */
  /* the artwork gently leans IN during its solo admire beat (feels bigger at the peak moment), then
     settles back to rest as the reward UI arrives — emphasis without permanently crowding the layout. */
  #chapterWin.chw-revealed .chwArtWrap { animation: chwArtAdmire 1.25s cubic-bezier(.25,.8,.3,1) both; }
  @keyframes chwArtAdmire { 0% { transform: scale(.995); } 55% { transform: scale(1.05); } 100% { transform: scale(1.045); } }
  #chapterWin.chw-settled .chwArtWrap { animation: chwArtSettle .55s ease-out both; }
  @keyframes chwArtSettle { from { transform: scale(1.045); } to { transform: scale(1); } }
  @keyframes chwArtIn { 0% { opacity: 0; transform: scale(.82); } 100% { opacity: 1; transform: scale(1); } }
  @keyframes chwColorBloom { 0% { opacity: 0; filter: saturate(.25) brightness(1.45); } 60% { opacity: 1; } 100% { opacity: 1; filter: none; } }
  #chapterWin .artEmblem { font-size: 96px; }
  #chapterWin .artCell .artTitle { display: none; }  /* redundant with the chwLabel below; the frame window stays clean */
  /* thumbs-up Sha peeks from the frame's bottom-right corner, popping in after the glass forms */
  #chapterWin .chwMascot {
    position: absolute; right: -50%; bottom: -9%; width: clamp(92px, 34%, 124px); z-index: 5;
    pointer-events: none; opacity: 0; -webkit-user-drag: none;
    filter: drop-shadow(0 6px 10px rgba(14,28,10,.55));
    transform-origin: 70% 90%;
  }
  #chapterWin.chw-settled .chwMascot { animation: chwMascotIn .62s cubic-bezier(.2,1.5,.4,1) .45s both; }   /* Sha joins at the celebration, not during the artwork's solo admire beat */
  @keyframes chwMascotIn {
    0%   { opacity: 0; transform: translateY(46%) rotate(-10deg) scale(.55); }
    70%  { opacity: 1; transform: translateY(-6%) rotate(5deg) scale(1.08); }
    100% { opacity: 1; transform: translateY(0) rotate(0) scale(1); }
  }
  /* crown is part of canvas_art.png now — drop the CSS crown */
  #chapterWin .chwArtWrap::before, #chapterWin .chwArtWrap::after { content: none; }
  /* HERO of the card: the restored artwork's name (big). A tiny kicker labels it; the rest is meta. */
  #chapterWin .chwLabel { display: flex; flex-direction: column; align-items: center; gap: 2px; z-index: 1; }
  #chapterWin .chwKicker { color: rgba(255,233,176,.72); font-size: 11px; font-weight: 700; letter-spacing: .07em; text-shadow: 0 1px 2px rgba(50,12,4,.7); }
  /* 무결점 챕터: the chapter window is PERFECTLY restored → a golden, fully-vivid variant (CSS-only, reuses the art) */
  #chapterWin .chwFlawKicker { color: #ffe27a; font-size: 13px; letter-spacing: .12em; text-shadow: 0 1px 0 #7a5512, 0 0 9px rgba(255,224,122,.8); }
  #chapterWin.chw-flawless .artGlass { filter: saturate(1.18) brightness(1.1); }   /* vivid "golden window" — NO gold halo/border (read as an errant yellow outline, esp. before the art reveals) */
  /* locked (not-yet-all-flawless): the window shows N/M glass pieces PLACED, the rest faint gaps — via an SVG shard
     mask on .artGlass set by showChapterVictory (조각이 채워진다). Placed pieces stay vivid (the carrot). */
  #chapterWin .chwLockKicker { color: rgba(255,233,176,.85); font-size: 12px; font-weight: 800; letter-spacing: .05em; text-shadow: 0 1px 2px rgba(50,12,4,.7); }
  #chapterWin .chwArtName { color: var(--gold); font-family: 'Jua', system-ui, sans-serif; font-weight: 400; font-size: 26px; line-height: 1; text-shadow: 0 2px 5px rgba(50,12,4,.85); }
  /* progress + new-area = quiet meta, one compact row below the reward */
  /* starlight settlement on the chapter card; the balance number counts up to its new total */
  #chapterWin .chwReward { display: flex; flex-direction: column; align-items: center; gap: 1px; z-index: 1; margin-top: 1px; }
  #chapterWin .chwReward .chwRewardAmt {
    color: var(--gold); font-family: 'Jua', system-ui, sans-serif; font-weight: 400; font-size: 20px; line-height: 1;
    -webkit-text-stroke: 1.2px var(--gold-deep); paint-order: stroke fill; text-shadow: 0 2px 0 var(--gold-deep), 0 3px 6px rgba(60,34,4,.45);
  }
  #chapterWin .chwReward .chwBalance { color: #ffe6b6; font-size: 12.5px; font-weight: 800; text-shadow: 0 1px 3px rgba(30,10,4,.7); }
  #chapterWin .chwReward .chwBalance b { color: #fff3c8; font-weight: 900; display: inline-block; min-width: 1.2em; }
  /* clean landing: a small pop + warm glow when the count-up reaches the total */
  #chapterWin .chwReward .chwBalance b.settle { animation: chwSettlePop .32s cubic-bezier(.34,1.56,.64,1); }
  @keyframes chwSettlePop {
    0%   { transform: scale(1.22); text-shadow: 0 0 11px rgba(255,216,120,.95), 0 0 4px rgba(255,240,190,.9); }
    60%  { transform: scale(.98); }
    100% { transform: scale(1); text-shadow: none; }
  }
  #chapterWin .chwStory { width: min(86vw, 360px); min-height: 42px; padding: 9px 15px; z-index: 1;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; text-align: center;
    color: rgba(255,250,240,.82); font-size: clamp(12px, 3.3vw, 13.5px); font-weight: 600; font-style: italic; line-height: 1.4;
    border: 1px solid rgba(255,234,174,.16); border-radius: 14px;
    background: rgba(10,27,37,.42); box-shadow: inset 0 1px rgba(255,255,255,.05);
    text-shadow: 0 1px 3px rgba(0,0,0,.6); }
  /* short 무결점 nudge as its OWN line (not a run-on with the story beat) — detail guidance lives in the map window viewer */
  #chapterWin .chwNudge { font-style: normal; font-weight: 800; font-size: clamp(11px, 3vw, 12.5px); color: #ffe6a6;
    text-shadow: 0 1px 2px rgba(50,12,4,.6); }
  #chapterWin .chwBtns { display: flex; flex-direction: column; gap: 10px; width: 100%; max-width: 260px; margin-top: 4px; z-index: 1; }
  #chapterWin .chwBtns button { width: 100%; aspect-ratio: 467 / 146; padding: 0 8% 3%; border: none; border-radius: 0;
    background: url('../../assets/common/btn_green.png') center / 100% 100% no-repeat; box-shadow: none;
    display: flex; align-items: center; justify-content: center;
    color: #fff8e9; font-weight: 900; letter-spacing: .3px;
    text-shadow: 0 2px 0 #2c7a1f, 0 3px 5px rgba(18,55,8,.5); transition: transform .08s, filter .12s; }
  #chapterWin .chwBtns button:active { transform: translateY(2px) scale(.985); filter: brightness(.95); box-shadow: none; }
  #chapterWin #chwContinue { font-size: clamp(18px, 5.4vw, 23px); }
  #chapterWin #chwReplay { font-size: clamp(15px, 4.4vw, 19px); max-width: 80%; margin: 0 auto; }
  /* 무결점 미달성: 챕터 다시하기(재도전 유도)를 위로, 계속하기를 아래 작게 */
  #chapterWin.chw-locked .chwBtns { flex-direction: column-reverse; }
  #chapterWin.chw-locked #chwReplay { font-size: clamp(18px, 5.4vw, 23px); max-width: 100%; }
  #chapterWin.chw-locked #chwContinue { font-size: clamp(15px, 4.4vw, 19px); max-width: 80%; margin: 0 auto; }
  /* ── 자물쇠/열쇠 미스터리 시스템 ── */
  .chwLockVeil {
    position: absolute; inset: 0; z-index: 5; pointer-events: none;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
    background: linear-gradient(165deg, rgba(26,10,2,.76) 0%, rgba(11,4,1,.86) 100%);
    backdrop-filter: blur(2px) saturate(.7); -webkit-backdrop-filter: blur(2px) saturate(.7);
    border-radius: 4px;
  }
  .chwLockVeil.chwVeilOut { animation: chwVeilOut .6s ease both; }
  @keyframes chwVeilOut { to { opacity: 0; } }
  .chwLockSvg { width: 42px; height: 42px; color: #d4a855; filter: drop-shadow(0 2px 10px rgba(200,146,26,.55)); flex-shrink: 0; }
  .chwLockSvg.chwLockJiggle { animation: chwLockJiggle .55s ease both; }
  @keyframes chwLockJiggle {
    0%   { transform: rotate(0) scale(1); }
    20%  { transform: rotate(-9deg) scale(1.1); filter: drop-shadow(0 0 14px rgba(246,200,60,.85)); color: #f6c83c; }
    40%  { transform: rotate(9deg) scale(1.12); filter: drop-shadow(0 0 20px rgba(246,200,60,1)); color: #f6c83c; }
    60%  { transform: rotate(-5deg) scale(1.06); color: #edb040; }
    80%  { transform: rotate(4deg) scale(1.03); }
    100% { transform: rotate(0) scale(0); opacity: 0; }
  }
  .chwKeyWrap { display: flex; align-items: center; justify-content: center; opacity: 0; }
  .chwKeyWrap.chwKeyIn  { animation: chwKeyIn  .55s cubic-bezier(.2,.8,.3,1) .1s both; }
  .chwKeyWrap.chwKeyFly { animation: chwKeyFly .5s  cubic-bezier(.4,0,.2,1.1)   both; }
  @keyframes chwKeyIn  { from { opacity:0; transform:translateY(10px) rotate(-10deg); } to { opacity:1; transform:translateY(0) rotate(0); } }
  @keyframes chwKeyFly { 0%{transform:translateY(0) rotate(0);} 55%{transform:translateY(-24px) rotate(-8deg) scale(1.06);} 80%{transform:translateY(-28px) rotate(5deg);} 100%{transform:translateY(-26px) rotate(-2deg);} }
  /* 잠금·무결점 애니 중 Sha 숨김 — 베일 걷힐 때 함께 등장 */
  #chapterWin.chw-locked .chwMascot { opacity: 0; pointer-events: none; }
  #chapterWin.chw-flawless .chwMascot { opacity: 0; transition: opacity .5s ease .1s; pointer-events: none; }
  #chapterWin.chw-flawless.chw-veil-done .chwMascot { opacity: 1; pointer-events: auto; }
  html[data-motion="reduced"] {
    .chwKeyWrap.chwKeyIn, .chwKeyWrap.chwKeyFly, .chwLockSvg.chwLockJiggle, .chwLockVeil.chwVeilOut { animation: none; opacity: 1; }
    #chapterWin.chw-flawless .chwMascot, #chapterWin.chw-locked .chwMascot { opacity: 1; }
  }
  @keyframes chwFade { from { opacity: 0; } to { opacity: 1; } }
  @keyframes chwBurstPulse { 0%,100% { opacity: .7; transform: scale(.96) rotate(0); } 50% { opacity: 1; transform: scale(1.05) rotate(8deg); } }
  @keyframes chwUiIn { 0% { opacity: 0; transform: translateY(10px); } 100% { opacity: 1; transform: translateY(0); } }
  @keyframes chwTitlePop { 0% { transform: scale(.4) translateY(-20px); opacity: 0; } 100% { transform: scale(1) translateY(0); opacity: 1; } }
  @keyframes chwStarPop { 0% { transform: scale(0) rotate(-25deg); } 100% { transform: scale(1) rotate(0); } }
  html[data-motion="reduced"] {
    #chapterWin.show, #chapterWin h2, #chapterWin .chwBurst, #chapterWin .chwStars span.on { animation: none; }
    /* no wind-up: show the formed glass + reward statically (frame ::after stays visible) */
    #chapterWin .artGlass, #chapterWin .chwArtWrap, #chapterWin .chwStars, #chapterWin .chwLabel, #chapterWin .chwReward, #chapterWin .chwStory, #chapterWin .chwBtns, #chapterWin .chwMascot {
      opacity: 1 !important; animation: none !important; }
  }
