﻿/* 스탯스토리 — 전투 연출 더하기(js/battle.js)
   스킬 막대(MP·스킬 단추), 스킬 효과(방패 막·약화·지운 보기·스킬 이름), 새 공격 모션(웅크림 → 돌진하며 무기를 손을 축으로 내려침,
   잔상·베기 궤적·별 섬광·히트스톱). 무기를 돌리는 감싸개 .hero-swing 은 js/art.js 의 heroFigure 가 만든다. */

/* ---------- 스킬 막대: 문제 카드 아래에 있고, 길게 내려도 화면 맨 아래에 붙어 따라온다(장면은 위에 붙어 있다) ---------- */
.skillbar {
  position: sticky; bottom: 0; z-index: 7;
  display: flex; align-items: center; gap: 14px;
  width: calc(100% - 32px); max-width: 860px; margin: -8px auto 0; padding: 10px 16px calc(10px + env(safe-area-inset-bottom, 0px));
  background: rgba(255, 250, 240, .97); border: 3px solid var(--ink); border-bottom: 0; border-radius: 18px 18px 0 0;
  box-shadow: 0 -4px 0 rgba(43, 33, 64, .1), 0 -10px 24px rgba(43, 33, 64, .12);
}
/* MP: 열 칸 막대와 숫자. 맞히면 차고(+1, 콤보가 이어지면 +2) 가득 차면 반짝인다 */
.sk-mp { position: relative; flex: 1 1 auto; min-width: 96px; display: flex; align-items: center; gap: 7px; }
.sk-mp-ic { flex: none; width: 24px; height: 24px; display: grid; place-items: center; }
.sk-mp-ic svg { width: 100%; height: 100%; display: block; }
.sk-mp-bar {
  position: relative; flex: 1 1 auto; min-width: 40px; max-width: 360px; height: 16px; overflow: hidden;
  border: 2.5px solid var(--ink); border-radius: 9px; background: #dfe8ff; box-shadow: inset 0 2px 0 rgba(43, 33, 64, .12);
}
.sk-mp-bar .fill { position: absolute; left: 0; top: 0; bottom: 0; width: 0; background: linear-gradient(180deg, #a9dcff 0%, #4f95ff 55%, #2f6fe0 100%); transition: width .35s ease-out; }
.sk-mp-bar::after { content: ''; position: absolute; inset: 0; pointer-events: none; background: repeating-linear-gradient(90deg, transparent 0 calc(10% - 2px), rgba(43, 33, 64, .28) calc(10% - 2px) 10%); }
.sk-mp-n { flex: none; font-family: var(--f-num); font-size: 17px; font-weight: 400; line-height: 1; color: var(--ink); white-space: nowrap; }
.sk-mp-n small { font-size: 12.5px; color: var(--ink-soft); }
.sk-mp-gain { position: absolute; right: 4px; top: -18px; pointer-events: none; font-family: var(--f-num); font-size: 16px; color: #2f6fe0; text-shadow: 0 0 3px #fff, 0 0 3px #fff; animation: sk-gain .9s ease-out forwards; }
@keyframes sk-gain { 0% { opacity: 0; transform: translateY(6px) scale(.8); } 25% { opacity: 1; transform: translateY(0) scale(1.12); } 100% { opacity: 0; transform: translateY(-12px); } }
.sk-mp.full .sk-mp-bar { animation: sk-full .8s ease-out; }
@keyframes sk-full { 40% { box-shadow: 0 0 0 3px #a9dcff, 0 0 16px #4f95ff; } }

/* 스킬 단추: 아이콘, 오른쪽 아래 MP 값, 왼쪽 위 키(Q W E R, 키보드 기기만), 이어지는 효과의 남은 문제 수(노란 점) */
.sk-slots { flex: none; display: flex; gap: 10px; }
.sk-btn {
  position: relative; flex: none; width: 50px; height: 50px; padding: 3px; cursor: pointer;
  border: 3px solid var(--ink); border-radius: 15px; background: #fff; box-shadow: 0 3px 0 var(--ink);
  transition: transform .12s, box-shadow .15s, background-color .2s;
}
.sk-btn .sk-ico { display: block; width: 100%; height: 100%; transition: filter .2s; }
.sk-btn .cost {
  position: absolute; right: -8px; bottom: -8px; min-width: 21px; height: 21px; padding: .14em 4px 0; display: grid; place-items: center;
  border: 2px solid var(--ink); border-radius: 11px; background: #2f6fe0; color: #fff; font-family: var(--f-num); font-size: 12.5px; line-height: 1;
}
.sk-btn .key { position: absolute; left: 4px; top: 2px; pointer-events: none; font-family: var(--f-num); font-size: 10.5px; line-height: 1; color: rgba(43, 33, 64, .55); }
.sk-btn .turns:not(:empty) {
  position: absolute; left: -8px; top: -8px; min-width: 20px; height: 20px; padding: .14em 4px 0; display: grid; place-items: center;
  border: 2px solid var(--ink); border-radius: 10px; background: var(--gold); color: var(--ink); font-family: var(--f-num); font-size: 12px; line-height: 1;
}
.sk-btn:not(.off):hover { transform: translateY(-2px); box-shadow: 0 5px 0 var(--ink), 0 0 0 3px var(--sk-c); }
.sk-btn:not(.off):active { transform: translateY(2px); box-shadow: 0 1px 0 var(--ink); }
.sk-btn:focus-visible { outline: 3px solid var(--violet); outline-offset: 3px; }
.sk-btn.off { cursor: default; box-shadow: 0 2px 0 rgba(43, 33, 64, .55); }
.sk-btn.off .sk-ico { filter: grayscale(.85) opacity(.5); }
.sk-btn.poor .cost { background: #9a93ad; }
/* 이번 문제에 걸어 둔 스킬(빛나며 숨쉰다) · 여러 문제 동안 이어지는 스킬 */
.sk-btn.armed { background: #fff; background: color-mix(in srgb, var(--sk-c) 18%, #fff); box-shadow: 0 3px 0 var(--ink), 0 0 0 3px var(--sk-c), 0 0 16px var(--sk-c); animation: sk-armed 1.1s ease-in-out infinite; }
.sk-btn.on { box-shadow: 0 3px 0 var(--ink), 0 0 0 3px var(--sk-c); }
.sk-btn.armed .sk-ico, .sk-btn.on .sk-ico { filter: none; }
@keyframes sk-armed { 50% { box-shadow: 0 3px 0 var(--ink), 0 0 0 3px var(--sk-c), 0 0 28px var(--sk-c); } }
.sk-btn.cast { animation: sk-cast-btn .56s cubic-bezier(.2, 1.6, .4, 1); }
@keyframes sk-cast-btn { 35% { transform: scale(1.18) rotate(-4deg); } }
.sk-btn.empty { display: block; cursor: default; background: rgba(43, 33, 64, .04); border-style: dashed; border-color: rgba(43, 33, 64, .3); box-shadow: none; }
@media (max-width: 420px) {
  .skillbar { gap: 10px; width: calc(100% - 20px); padding: 8px 12px calc(8px + env(safe-area-inset-bottom, 0px)); border-radius: 16px 16px 0 0; }
  .sk-slots { gap: 8px; }
  .sk-btn { width: 44px; height: 44px; padding: 2px; border-radius: 13px; }
  .sk-mp { min-width: 0; gap: 5px; }
  .sk-mp-ic { width: 20px; height: 20px; }
  .sk-mp-n { font-size: 15px; }
}
/* 스킬 막대가 있는 전투에서는 알림(toast)을 막대 위로 */
#app:has(.skillbar) .toast { bottom: 96px; }

/* ---------- 문제 카드: 걸어 둔 스킬 ---------- */
.sk-armed {
  display: flex; align-items: center; gap: 9px; margin: 8px 0 2px; padding: 6px 12px 6px 8px;
  border: 2.5px dashed var(--sk-c, #4f95ff); border-radius: 12px; background: #fff; background: color-mix(in srgb, var(--sk-c, #4f95ff) 12%, #fff);
  font-family: var(--f-ui); font-size: 15px; line-height: 1.35; color: var(--ink); animation: pop-in .35s ease-out;
}
.sk-armed .sk-ico { flex: none; width: 30px; height: 30px; }
.sk-armed b { font-weight: 400; margin-right: 4px; }
/* 지운 보기(편향 걸러내기), 다시 생각하기로 지운 첫 오답 */
.choice.gone { opacity: .45; filter: grayscale(1); text-decoration: line-through; text-decoration-thickness: 2px; cursor: default; animation: choice-gone .45s ease-out; }
.choice.gone .no { background: #e4dff0; }
.choice.missed { background: #ffe5e9; border-color: var(--bad); }
@keyframes choice-gone { 0% { opacity: 1; filter: none; transform: scale(1); } 30% { transform: scale(1.02) rotate(-.6deg); } 100% { opacity: .45; transform: scale(1); } }

/* ---------- 장면: 스킬 이름·큰 외침, 방패 막, 약화 ---------- */
.floater .sk-name {
  display: block; white-space: nowrap; font-family: var(--f-display); font-size: clamp(17px, 2.6vw, 24px); color: #fff;
  -webkit-text-stroke: 1.5px var(--ink); text-shadow: 0 3px 0 var(--ink), 0 0 14px var(--sk-c, #4f95ff);
}
.floater .sk-big {
  display: block; white-space: nowrap; font-family: var(--f-display); font-size: clamp(30px, 5vw, 52px); color: #fff;
  -webkit-text-stroke: 2px var(--ink); text-shadow: 0 4px 0 var(--ink), 0 0 20px var(--sk-c, #ff4d63); animation: sk-big .5s cubic-bezier(.2, 1.6, .4, 1);
}
@keyframes sk-big { 0% { transform: scale(.4); } 60% { transform: scale(1.15); } 100% { transform: scale(1); } }
.actor .act { position: relative; } /* 방패 막·잔상이 주인공 상자에 맞춰 자리 잡게 */
/* 방패(중앙값 방패·A/B 테스트를 걸었을 때)와 산포 줄이기(점선): 주인공을 감싸는 물방울 막 */
.actor.player.sk-shield .act::after, .actor.player.sk-guard .act::after {
  content: ''; position: absolute; left: -16%; right: -16%; top: -8%; bottom: -4%; z-index: 6; pointer-events: none; border-radius: 50% 50% 46% 46%;
  border: 3px solid rgba(127, 196, 255, .95);
  background: radial-gradient(ellipse at 50% 35%, rgba(255, 255, 255, .28), rgba(120, 190, 255, .14) 55%, rgba(79, 149, 255, .32) 100%);
  box-shadow: inset 0 0 18px rgba(79, 149, 255, .55), 0 0 14px rgba(79, 149, 255, .5);
  animation: sk-bubble 1.6s ease-in-out infinite;
}
.actor.player.sk-guard:not(.sk-shield) .act::after { border-style: dashed; border-color: rgba(127, 196, 255, .85); background: radial-gradient(ellipse at 50% 35%, rgba(255, 255, 255, .12), rgba(79, 149, 255, .18) 100%); }
@keyframes sk-bubble { 50% { transform: scale(1.03); box-shadow: inset 0 0 24px rgba(79, 149, 255, .7), 0 0 22px rgba(79, 149, 255, .6); } }
.actor.player.sk-block .act { animation: sk-block .5s ease-out; }
@keyframes sk-block { 25% { transform: translateX(-4%); filter: brightness(1.35); } }
/* 중심극한의 힘(주는 피해 ↑): 붉은 금빛 기운 */
.actor.player.sk-rally .idle { animation: breathe 2.2s ease-in-out infinite, sk-rally .9s ease-in-out infinite alternate; }
@keyframes sk-rally { from { filter: drop-shadow(0 0 4px rgba(255, 120, 90, .9)) drop-shadow(0 0 10px rgba(255, 77, 99, .55)); } to { filter: drop-shadow(0 0 6px rgba(255, 185, 46, .95)) drop-shadow(0 0 16px rgba(255, 77, 99, .7)); } }
/* 공격 스킬을 걸면 무기가 그 스킬 색으로 빛난다. 결론의 일격은 몸 둘레까지 */
.actor.player.sk-charged .hero-swing { animation: sk-charge .7s ease-in-out infinite alternate; }
@keyframes sk-charge { from { filter: drop-shadow(0 0 3px #fff) drop-shadow(0 0 8px var(--sk-c, #ffb92e)); } to { filter: drop-shadow(0 0 5px #fff) drop-shadow(0 0 18px var(--sk-c, #ffb92e)); } }
.actor.player.sk-ult .idle { filter: drop-shadow(0 0 6px #ffe066) drop-shadow(0 0 18px #ffb000); }
/* 스킬을 쓰는 순간 살짝 뛰어오른다 */
.actor.player.sk-cast .act { animation: sk-cast-hero .56s ease-out; }
@keyframes sk-cast-hero { 30% { transform: translateY(-7%) scale(1.04); } }
/* 심슨의 역설 간파: 몬스터가 빛을 잃고 이름표에 '약화' */
.actor.monster.sk-weak .idle { filter: saturate(.6) brightness(.95) drop-shadow(0 0 6px rgba(155, 107, 255, .85)); }
.mon-plate .sk-weak-tag { flex: none; padding: .14em 6px 0; border: 2px solid var(--ink); border-radius: 7px; background: #9b6bff; color: #fff; font-family: var(--f-ui); font-size: 12px; line-height: 1.25; }

/* ---------- 새 스킬 카드(승리 창·새 스킬 알림) ---------- */
.drop-card .ico .sk-ico { width: 100%; height: 100%; display: block; }
.sk-cost-pill { display: inline-block; margin-left: 4px; padding: .14em 7px 0; border-radius: 999px; background: #2f6fe0; color: #fff; font-family: var(--f-num); font-size: 12.5px; line-height: 1.3; vertical-align: 2px; }

/* ---------- 공격 모션 ----------
   몸(.act): 웅크리며 뒤로(14%) → 몬스터 앞으로 돌진하며 앞으로 기울임(32%, 이때 맞는다) → 잠깐 머묾 → 튕겨 돌아옴.
   무기(.hero-swing, 손이 축): 뒤로 젖힘(-66°) → 내려침(+98°) → 제자리. 맞는 순간 장면 전체가 잠깐 멈춘다(.scene.hitstop). */
.actor.player.atk { z-index: 5; } /* 공격하는 동안은 몬스터 앞에(무기가 가려지지 않게) */
.actor.player.atk .act { animation: atk-body .68s cubic-bezier(.3, .7, .3, 1); }
.actor.player.atk .hero-swing { animation: wpn-swing .68s cubic-bezier(.3, .7, .3, 1); filter: drop-shadow(0 0 3px #fff) drop-shadow(0 0 9px rgba(255, 214, 120, .95)); }
@keyframes atk-body {
  0% { transform: translateX(0) rotate(0) scale(1); }
  14% { transform: translateX(-7%) rotate(-6deg) scale(1.03, .95); }
  32% { transform: translateX(var(--lunge, 120px)) rotate(9deg) scale(1.02, .99); }
  50% { transform: translateX(var(--lunge, 120px)) rotate(5deg) scale(1); }
  66% { transform: translateX(calc(var(--lunge, 120px) * .9)) rotate(-3deg); }
  100% { transform: translateX(0) rotate(0) scale(1); }
}
@keyframes wpn-swing {
  0% { transform: rotate(0deg); }
  14% { transform: rotate(-66deg); }
  31% { transform: rotate(98deg); }
  50% { transform: rotate(84deg); }
  100% { transform: rotate(0deg); }
}
.scene.hitstop .actor .act, .scene.hitstop .actor .idle, .scene.hitstop .actor .hero-swing { animation-play-state: paused !important; }
/* 돌진 잔상: 주인공 그림을 복제해 지나가는 자리에 두고 곧 사라진다(색은 그 공격의 궤적 색) */
.actor .ghost { position: absolute; left: 0; right: 0; bottom: 0; z-index: -1; pointer-events: none; opacity: .5; filter: brightness(1.5) saturate(.4) drop-shadow(0 0 6px var(--ghost, rgba(255, 210, 90, .9))); animation: ghost-fade .34s ease-out forwards; }
.actor .ghost * { animation: none !important; }
.actor .ghost.g-blue { --ghost: rgba(120, 190, 255, .95); }
.actor .ghost.g-purple { --ghost: rgba(170, 130, 255, .95); }
.actor .ghost.g-red { --ghost: rgba(255, 110, 125, .95); }
.actor .ghost.g-green { --ghost: rgba(90, 220, 140, .95); }
@keyframes ghost-fade { 0% { opacity: .55; } 100% { opacity: 0; } }
/* 베기 궤적(초승달, 흰 속 → 색 테두리). flip 은 거꾸로 그어 X자를 만든다(치명타·결론의 일격·5콤보) */
.scene .slash-arc {
  position: absolute; z-index: 8; pointer-events: none; overflow: visible; opacity: 0;
  transform: translate(-50%, -50%) rotate(-60deg) scale(.5); filter: drop-shadow(0 0 2px #fff) drop-shadow(0 0 10px var(--arc));
  animation: arc-sweep .36s cubic-bezier(.15, .8, .3, 1) forwards;
}
.scene .slash-arc.flip { animation-name: arc-sweep-flip; }
@keyframes arc-sweep { 0% { opacity: 0; transform: translate(-50%, -50%) rotate(-60deg) scale(.5); } 22% { opacity: 1; } 70% { opacity: .95; } 100% { opacity: 0; transform: translate(-50%, -50%) rotate(14deg) scale(1.12); } }
@keyframes arc-sweep-flip { 0% { opacity: 0; transform: translate(-50%, -50%) scaleX(-1) rotate(-60deg) scale(.5); } 22% { opacity: 1; } 70% { opacity: .95; } 100% { opacity: 0; transform: translate(-50%, -50%) scaleX(-1) rotate(14deg) scale(1.12); } }
/* 맞는 순간 번쩍이는 별 */
.scene .hit-star { position: absolute; z-index: 8; pointer-events: none; opacity: 0; transform: translate(-50%, -50%) scale(.2); filter: drop-shadow(0 0 10px var(--arc)); animation: star-pop .32s ease-out forwards; }
@keyframes star-pop { 0% { opacity: 1; transform: translate(-50%, -50%) scale(.2) rotate(0); } 40% { opacity: 1; transform: translate(-50%, -50%) scale(1.1) rotate(10deg); } 100% { opacity: 0; transform: translate(-50%, -50%) scale(1.35) rotate(24deg); } }

@media (prefers-reduced-motion: reduce) {
  .actor.player.atk .act, .actor.player.atk .hero-swing { animation-duration: .2s; }
  .scene .slash-arc, .scene .hit-star, .actor .ghost { display: none; }
  .actor.player.sk-shield .act::after, .actor.player.sk-guard .act::after, .sk-btn.armed, .actor.player.sk-charged .hero-swing { animation: none; }
}
