﻿/* ─────────────────────────────────────────────
   레트로 도트 게임 스타일

   한글 픽셀 폰트가 있으면 분위기가 확 산다.
   갈무리(Galmuri) 웹폰트를 쓰려면 아래 @font-face 주석을 풀고
   폰트 파일을 static/fonts/ 에 넣으면 된다.
   없으면 기본 고정폭 글꼴로 표시된다.
   ───────────────────────────────────────────── */

/*
@font-face {
    font-family: 'Galmuri11';
    src: url('/static/fonts/Galmuri11.woff2') format('woff2');
    font-display: swap;
}
*/

* {
    box-sizing: border-box;
}

body {
    margin: 0;
    background: #12121c;
    color: #d8d8e8;
    font-family: 'Galmuri11', 'DungGeunMo', 'Neo둥근모', monospace;
    font-size: 14px;
    /* 도트가 뭉개지지 않도록 */
    image-rendering: pixelated;
    -webkit-font-smoothing: none;
}

.hidden {
    display: none !important;
}

/* ── 접속 화면 ── */
.screen {
    min-height: 100vh;
}

#login {
    display: flex;
    align-items: center;
    justify-content: center;
}

.panel {
    background: #1e1e2e;
    border: 3px solid #3a3a52;
    padding: 32px 28px;
    text-align: center;
    width: 300px;
    /* 도트 느낌: 둥근 모서리 대신 각지게 + 두꺼운 그림자 */
    box-shadow: 6px 6px 0 #0a0a12;
}

.panel h1 {
    margin: 0 0 4px;
    color: #ffc857;
    letter-spacing: 2px;
}

.panel .sub {
    margin: 0 0 22px;
    color: #7a7a96;
    font-size: 12px;
}

#name, #pw, #chat {
    width: 100%;
    padding: 10px;
    background: #12121c;
    border: 2px solid #3a3a52;
    color: #d8d8e8;
    font-family: inherit;
    font-size: 16px;   /* 16px 미만이면 아이폰에서 입력 시 화면이 확대됨 */
}

#pw {
    margin-top: 8px;
}

#name:focus, #pw:focus, #chat:focus {
    outline: none;
    border-color: #6ad4ff;
}

/* 로그인 안내 / 오류 문구 */
.login-msg {
    min-height: 18px;
    margin: 10px 0 0;
    font-size: 12px;
    color: #ff8ab0;
}

.login-hint {
    margin: 6px 0 0;
    font-size: 11px;
    color: #6a6a86;
    line-height: 1.5;
}

button {
    background: #3a3a52;
    color: #d8d8e8;
    border: 2px solid #55557a;
    padding: 10px 14px;
    font-family: inherit;
    font-size: 14px;
    cursor: pointer;
}

button:hover {
    background: #4a4a68;
}

button:active {
    transform: translate(1px, 1px);
}

#enter {
    width: 100%;
    margin-top: 12px;
    background: #ffc857;
    border-color: #ffdd8a;
    color: #12121c;
}

/* ── 게임 화면 ────────────────────────────────
   창 전체를 꽉 채우는 구조.
     #game        세로로 [본문 / 상태줄 / 스킬바 / 퀵슬롯]
     .main-row    가로로 [게임 화면 / 로그]
   게임 화면은 남는 공간을 전부 가져가고,
   보이는 칸 수(VIEW_W/VIEW_H)는 창 크기에 맞춰 game.js 가 다시 계산한다.
   (예전에는 폭이 고정이라 넓은 화면에서 오른쪽이 텅 비었다)
   ───────────────────────────────────────────── */
#game {
    height: 100vh;
    height: 100dvh;        /* 폰 주소창이 접혔다 펴져도 흔들리지 않게 */
    padding: 8px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    overflow: hidden;      /* 전체 페이지는 스크롤되지 않는다 */
}

.main-row {
    display: flex;
    gap: 8px;
    flex: 1;
    min-height: 0;         /* 이게 없으면 자식이 넘쳐도 안 줄어든다 */
}

.stage {
    background: #0a0a12;
    border: 3px solid #3a3a52;
    flex: 1;               /* 남는 가로 공간을 전부 차지 */
    min-width: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    position: relative;    /* 방향 버튼을 겹쳐 놓기 위해 */
}

#screen {
    display: block;
    flex: 1;
    min-height: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;   /* 비율을 지키며 칸을 꽉 채운다 */
    image-rendering: pixelated;
}

/* 로그·채팅 칸. 폭은 창 크기에 따라 적당히 (너무 넓지도 좁지도 않게) */
.side {
    flex: 0 0 clamp(260px, 22vw, 400px);
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

/* ── 아래 조작부 ──────────────────────────────
   ★ '읽는 것'과 '누르는 것'을 한 줄에 섞지 않는다.
     전에는 HP 게이지 옆에 상점 버튼이 있어서 둘 다 눈에 안 들어왔다.

     왼쪽 vitals  전투 중 계속 보는 것 (HP/MP/상태이상)
     오른쪽 bars  전투 중 손이 가는 것 (QWER · 퀵슬롯)
   ─────────────────────────────────────────── */
.dock {
    display: flex;
    align-items: stretch;
    gap: 10px;
    flex: 0 0 auto;        /* 세로 배치에서 눌리지 않게 */
}

.vitals {
    flex: 0 0 clamp(170px, 20vw, 260px);
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 5px;
    background: #1e1e2e;
    border: 3px solid #3a3a52;
    padding: 7px 10px;
}

.bars {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 5px;
}

/* 참고 숫자 한 줄. 분 단위로만 바뀌므로 작고 흐리게. */
.statline {
    display: flex;
    align-items: center;
    gap: 12px;
    flex: 0 0 auto;
    padding: 3px 10px;
    background: #14141f;
    border: 2px solid #2a2a3e;
    font-size: 12px;
    color: #8a8aa6;
}

.statline .st-gauge {
    flex: 1;
    min-width: 60px;
    max-width: 220px;
}

.st-exp {
    font-size: 11px;
    color: #6a6a8a;
    white-space: nowrap;
}

.st-gauge {
    flex: 1;
    min-width: 90px;
}

/* 창 여는 버튼은 지역 이름 줄로 올렸다 (가끔 누르는 것) */
.zonebar-btns {
    display: flex;
    gap: 5px;
    margin-left: auto;
}

.zonebar-btns .hud-btn {
    padding: 3px 9px;
    font-size: 12px;
}

.zonebar-btns .hud-btn b {
    color: #6a6a8a;
    font-size: 10px;
    margin-left: 3px;
}

.st-lv, .st-atk {
    font-size: 14px;
    white-space: nowrap;
}

.st-lv b {
    color: #ffc857;
    font-size: 18px;
}

.st-atk b {
    color: #ff8ab0;
}

.bar-label {
    font-size: 11px;
    color: #7a7a96;
    margin-bottom: 2px;
}

/* 도트 느낌을 위해 둥근 모서리 없이 각지게 */
.bar {
    height: 10px;
    background: #0a0a12;
    border: 2px solid #3a3a52;
}

/* HP/MP 는 전투 중 계속 봐야 하므로 두껍게 */
.bar.big {
    height: 16px;
}

/* 남은 체력이 적으면 게이지가 뛴다. 숫자를 안 읽어도 위험을 안다. */
.fill.hp.low {
    animation: hpLow 0.7s steps(2) infinite;
}

@keyframes hpLow {
    0%, 100% { background: #ff6b6b }
    50%      { background: #ffd0d0 }
}

.fill {
    height: 100%;
    width: 100%;
    transition: width 0.15s linear;
}

.fill.hp {
    background: #ff6b6b;
}

.fill.exp {
    background: #6ad4ff;
}

.st-def b {
    color: #9be564;
}

.st-gold b {
    color: #ffc857;
}

.hud-btn {
    width: auto;
    padding: 6px 12px;
    margin: 0;
    white-space: nowrap;
}

.hud-btn:disabled {
    opacity: 0.4;
    cursor: default;
}
/* 소리를 끈 상태. 눌러서 켤 수 있으므로 :disabled 와 달리 반쯤만 죽인다 */
.hud-btn.off {
    opacity: 0.45;
    text-decoration: line-through;
}

/* ── 캐릭터 생성 화면 ── */
#create {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px 10px;
}

.panel.wide {
    width: min(560px, 96vw);
    text-align: left;
}

.panel.wide h1 {
    text-align: center;
}

.pick-title {
    margin: 16px 0 8px;
    font-size: 13px;
    color: #ffc857;
}

.pick-list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
    gap: 6px;
}

.pick-card {
    background: #12121c;
    border: 2px solid #3a3a52;
    padding: 9px;
    cursor: pointer;
    font-size: 11px;
    line-height: 1.5;
}

.pick-card:hover {
    background: #22223a;
}

.pick-card.on {
    border-color: #ffc857;
    background: #2a2438;
}

.pick-name {
    font-size: 14px;
    margin-bottom: 2px;
}

.pick-trait {
    color: #9be564;
}

.create-preview {
    margin: 16px 0 10px;
    padding: 10px;
    background: #12121c;
    border: 2px solid #3a3a52;
    font-size: 12px;
    line-height: 1.7;
    min-height: 40px;
}

#createBtn {
    width: 100%;
    background: #ffc857;
    border-color: #ffdd8a;
    color: #12121c;
}

#createBtn:disabled {
    background: #3a3a52;
    border-color: #45455f;
    color: #7a7a96;
    cursor: default;
}

button.ghost {
    width: 100%;
    margin-top: 6px;
    background: transparent;
    border-color: #3a3a52;
    color: #7a7a96;
}

/* ── 스킬바 / 스킬창 ── */
.skillbar .qslot.skill {
    width: 76px;
    height: 46px;
    border-color: #45455f;
}

.qslot.skill .sname {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 12px;
    text-align: center;
    font-size: 11px;
    color: #d8d8e8;
}

.qslot.skill.lack {
    opacity: 0.45;   /* 마나 부족 */
}

.qslot.skill:not(.empty):hover {
    border-color: #ffc857;
}

.slot-row {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
}

.slot-cell {
    flex: 1;
    min-width: 90px;
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 8px;
    background: #12121c;
    border: 2px solid #45455f;
    font-size: 12px;
    cursor: pointer;
}

.slot-cell.empty {
    color: #55556e;
    cursor: default;
}

.skill-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: 5px;
}

.skill-item {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 8px;
    background: #12121c;
    border: 2px solid #3a3a52;
    font-size: 12px;
    cursor: pointer;
}

.skill-item:hover {
    background: #262638;
}

.skill-item.on {
    border-color: #ffc857;
}

.skill-item.passive,
.skill-item.locked {
    cursor: default;
}

.skill-item.locked {
    opacity: 0.45;
}

.skill-item .nm {
    flex-shrink: 0;
}

.skill-item .badge {
    margin-left: auto;
    font-size: 10px;
    color: #ffc857;
}

.fill.mp {
    background: #6a8cff;
}

/* ── 퀵슬롯 ── */
.quickbar {
    display: flex;
    gap: 4px;
    flex-wrap: wrap;
    flex: 0 0 auto;        /* 세로 배치에서 눌리지 않게 */
    justify-content: center;
}

.qslot {
    position: relative;
    width: 46px;
    height: 46px;
    background: #1e1e2e;
    border: 3px solid #3a3a52;
    cursor: pointer;
}

.qslot.empty {
    cursor: default;
    opacity: 0.55;
}

.qslot:not(.empty):hover {
    border-color: #6ad4ff;
}

.qkey {
    position: absolute;
    top: 1px;
    left: 3px;
    font-size: 10px;
    color: #7a7a96;
}

.qdot {
    position: absolute;
    left: 50%;
    top: 52%;
    width: 16px;
    height: 16px;
    transform: translate(-50%, -50%);
}

.qcnt {
    position: absolute;
    right: 3px;
    bottom: 1px;
    font-size: 10px;
    color: #d8d8e8;
}

/* ── 모달 (가방 / 상점) ── */
.modal {
    position: fixed;
    inset: 0;
    background: #00000099;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 100;
}

.modal-box {
    background: #1e1e2e;
    border: 3px solid #3a3a52;
    box-shadow: 6px 6px 0 #0a0a12;
    width: min(680px, 94vw);
    max-height: min(88vh, 88dvh);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.modal-head {
    flex: 0 0 auto;        /* 제목줄은 항상 보인다 */
}

.modal-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 10px 14px;
    background: #262638;
    border-bottom: 3px solid #3a3a52;
    font-size: 15px;
    color: #ffc857;
}

.modal-head .close {
    width: auto;
    margin: 0;
    padding: 2px 10px;
    background: #55223a;
    border-color: #7a3355;
}

.bag-body {
    display: flex;
    gap: 14px;
    padding: 14px;
    overflow-y: auto;
    min-height: 0;         /* flex 안에서 overflow 가 실제로 동작하려면 필요 */
    scrollbar-width: thin;
    scrollbar-color: #3a3a52 #1e1e2e;
}

.modal-box.narrow {
    width: min(430px, 94vw);
}

/* 장비창: 캐릭터 미리보기 */
.gear-preview {
    flex-shrink: 0;
    text-align: center;
}

#gearCanvas {
    border: 3px solid #3a3a52;
    background: #12121c;
    image-rendering: pixelated;
    display: block;
}

.gear-name {
    margin-top: 8px;
    font-size: 12px;
    color: #ffc857;
}

.gear-stats {
    background: #12121c;
    border: 2px solid #3a3a52;
    padding: 8px 10px;
}

.stat-row {
    display: flex;
    justify-content: space-between;
    font-size: 12px;
    padding: 3px 0;
}

.stat-row .plus {
    color: #9be564;
    font-size: 10px;
}

.stat-sep {
    margin: 8px 0 4px;
    padding-top: 6px;
    border-top: 2px solid #3a3a52;
    font-size: 11px;
    color: #ffc857;
}

.stat-row .gold {
    color: #ffc857;
}

/* 상점 수량 버튼 (1 / 10 / 전부) */
.amt {
    display: flex;
    gap: 3px;
    flex-shrink: 0;
}

.amt button {
    width: auto;
    margin: 0;
    padding: 3px 7px;
    font-size: 11px;
    background: #2c2c42;
    border: 2px solid #45455f;
}

.amt button:hover {
    background: #3d3d5a;
    border-color: #6ad4ff;
}

.equip-col {
    width: 170px;
    flex-shrink: 0;
}

.inv-col {
    flex: 1;
    min-width: 200px;
}

.col-title {
    font-size: 12px;
    color: #7a7a96;
    margin-bottom: 8px;
}

.dim {
    color: #7a7a96;
    font-size: 11px;
}

.slot-label {
    font-size: 11px;
    color: #7a7a96;
    margin-bottom: 2px;
}

.slot-item {
    padding: 10px;
    background: #12121c;
    border: 2px solid #3a3a52;
    margin-bottom: 10px;
    cursor: pointer;
    font-size: 13px;
}

.slot-item.empty {
    color: #55556e;
    cursor: default;
}

.inv-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 6px;
}

.inv-cell {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 8px;
    background: #12121c;
    border: 2px solid #3a3a52;
    cursor: pointer;
    font-size: 12px;
}

.inv-cell:hover {
    background: #262638;
}

/* 전설 등급은 은은하게 빛난다 */
.inv-cell.legendary,
.slot-item.legendary {
    background: #2a2214;
    box-shadow: 0 0 8px rgba(255, 176, 32, 0.45);
    animation: legend 1.6s ease-in-out infinite;
}

/* 아티팩트: 전설보다 한 단계 위. 색이 돌아가며 바뀐다 */
.inv-cell.artifact,
.slot-item.artifact {
    background: #2a1430;
    box-shadow: 0 0 12px rgba(255, 79, 216, 0.6);
    animation: artifact 2.2s linear infinite;
}

@keyframes artifact {
    0%   { box-shadow: 0 0 10px rgba(255, 79, 216, 0.7); border-color: #ff4fd8; }
    33%  { box-shadow: 0 0 14px rgba(127, 216, 255, 0.7); border-color: #7fd8ff; }
    66%  { box-shadow: 0 0 14px rgba(255, 200, 87, 0.7); border-color: #ffc857; }
    100% { box-shadow: 0 0 10px rgba(255, 79, 216, 0.7); border-color: #ff4fd8; }
}

/* 아티팩트 고유 능력 설명 */
.unique {
    margin: 4px 0;
    padding: 3px 6px;
    background: #2a1430;
    border-left: 3px solid #ff4fd8;
    color: #ff9ae8;
    font-size: 11px;
    line-height: 1.4;
}

@keyframes legend {
    0%, 100% { box-shadow: 0 0 6px rgba(255, 176, 32, 0.35); }
    50%      { box-shadow: 0 0 14px rgba(255, 176, 32, 0.75); }
}

/* 아이템 도트 아이콘 */
.icon {
    flex-shrink: 0;
    image-rendering: pixelated;
    vertical-align: middle;
}

.slot-item {
    display: flex;
    align-items: center;
    gap: 8px;
}

.qslot .icon {
    position: absolute;
    left: 50%;
    top: 52%;
    transform: translate(-50%, -50%);
}

.inv-cell .nm, .shop-row .nm {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.inv-cell .cnt {
    color: #7a7a96;
}

.tip {
    margin: 10px 0 0;
    font-size: 11px;
    color: #6a6a86;
    line-height: 1.6;
}

/* 상점 목록 */
.shop-list {
    display: flex;
    flex-direction: column;
    gap: 4px;
    max-height: 46vh;
    overflow-y: auto;
}

.shop-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px;
    background: #12121c;
    border: 2px solid #3a3a52;
    cursor: pointer;
    font-size: 12px;
}

.shop-row:hover {
    background: #262638;
}

.shop-row.cant {
    opacity: 0.45;
}

/* ── 스킬 쿨타임 ── */
/* 위에서 아래로 차오르는 어두운 막 - 줄어들수록 걷힌다 */
.cd-veil {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    background: rgba(6, 6, 14, 0.78);
    pointer-events: none;
}

.cd-num {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 17px;
    font-weight: bold;
    color: #ffc857;
    text-shadow: 1px 1px 0 #0a0a12;
    pointer-events: none;
}

.qslot.cooling {
    border-color: #55557a;
}

/* ── 스킬 숙련도 ── */
.skill-item .rank {
    color: #ffc857;
    font-size: 11px;
    margin-left: 6px;
}

.up-btn {
    margin-left: 6px;
    padding: 0 7px;
    background: #2a4a1e;
    color: #9be564;
    border: 2px solid #4a7a34;
    font: inherit;
    font-size: 11px;
    cursor: pointer;
}

.up-btn:hover {
    background: #3a6a28;
}

/* ── 종족 특성 / 능력치 ── */
.trait {
    border: 2px solid #3a3a52;
    padding: 6px 8px;
    margin-bottom: 8px;
    font-size: 12px;
}

/* 조건이 충족돼 지금 효과가 켜져 있을 때 */
.trait.on {
    border-color: #ffb020;
    background: #2a2214;
}

.trait .fire {
    color: #ffb020;
}

.points {
    border: 2px solid #9be564;
    background: #16220f;
    padding: 5px 8px;
    margin-bottom: 8px;
    font-size: 12px;
    color: #9be564;
}

/* 힘·민첩·지능 줄은 조금 더 눈에 띄게 */
.stat-row.core {
    background: #16162a;
}

.stat-note {
    font-size: 10px;
    color: #6a6a8a;
    padding: 0 6px 4px;
    margin-top: -2px;
}

.pt-btn {
    margin-left: 6px;
    padding: 0 7px;
    background: #2a4a1e;
    color: #9be564;
    border: 2px solid #4a7a34;
    font: inherit;
    font-size: 12px;
    cursor: pointer;
}

.pt-btn:hover {
    background: #3a6a28;
}

/* ── 지금 있는 곳 표시 ── */
.zonebar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 4px 8px;
    background: #14141f;
    border-bottom: 2px solid #2a2a3e;
    font-size: 13px;
    letter-spacing: 1px;
    flex: 0 0 auto;        /* 게임 화면 위에 항상 붙어 있다 */
}

#zoneName {
    color: #9be564;
}

/* 던전 안에서는 색을 바꿔 '여기는 위험한 곳'임을 알린다 */
#zoneName.in-dungeon {
    color: #ffb020;
    text-shadow: 0 0 6px rgba(255, 176, 32, 0.5);
}

.zonebar .best {
    color: #6a6a8a;
    font-size: 11px;
}

/* ── 직업 전용 아이템 ── */
/* 다른 직업 전용은 흐리게 + 대각선 빗금으로 '내 것이 아님'을 알린다 */
.inv-cell.otherjob,
.shop-row.otherjob {
    opacity: 0.42;
    background-image: repeating-linear-gradient(
        45deg, transparent 0 5px, rgba(255, 90, 90, 0.14) 5px 10px);
}

.jobok {
    color: #9be564;
}

.jobno {
    color: #ff6b6b;
}

.price {
    color: #ffc857;
}

.price.sell {
    color: #9be564;
}

/* 아이템 설명 툴팁 */
.tooltip {
    position: fixed;
    z-index: 200;
    max-width: 210px;
    padding: 8px 10px;
    background: #0a0a12;
    border: 2px solid #55557a;
    font-size: 11px;
    line-height: 1.7;
    pointer-events: none;
}

/* 텍스트 로그 (머드의 핵심) */
/* 로그는 남는 높이를 채운다 (게임 화면 높이에 맞춰짐).
   고정 높이를 주면 게임 화면보다 길어지거나 짧아져서 어색하다. */
.log {
    background: #0a0a12;
    border: 3px solid #3a3a52;
    padding: 8px 10px;
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    line-height: 1.55;
    font-size: 13px;
    word-break: break-all;
    /* 스크롤바를 어두운 배경에 맞춘다 */
    scrollbar-width: thin;
    scrollbar-color: #3a3a52 #0a0a12;
}

.log::-webkit-scrollbar {
    width: 10px;
}

.log::-webkit-scrollbar-track {
    background: #0a0a12;
}

.log::-webkit-scrollbar-thumb {
    background: #3a3a52;
    border: 2px solid #0a0a12;
}

/* ── 로그 한 줄 ───────────────────────────────
   ★ 색만 6개 늘리면 무지개가 되어 전보다 더 안 읽힌다.
     세 가지를 같이 쓴다.
       왼쪽 띠   스크롤할 때 눈이 띠만 따라가면 된다
       밝기 차이 중요한 것만 밝게, 시스템은 흐리게 죽인다
       ×N 접기   같은 말이 연달아 오면 한 줄로 합친다 (core.js)
   ─────────────────────────────────────────── */
.log .line {
    margin-bottom: 2px;
    padding: 1px 0 1px 8px;
    border-left: 3px solid transparent;
    color: #b8b8cc;              /* 기본 안내 - 무난한 밝기 */
}

.log .line.off { display: none; }   /* 탭에서 걸러진 줄 */

/* 내가 준 피해·처치 - 시원한 초록 */
.log .hit  { border-left-color: #6ad46a; color: #a8e6a8; }
/* ★ 내가 받은 피해 - 가장 눈에 띄어야 한다. 배경까지 깐다. */
.log .hurt { border-left-color: #ff5555; color: #ff9a9a;
             background: rgba(255, 60, 60, .09); }
/* 획득 - 금색 */
.log .gain { border-left-color: #ffc857; color: #ffd98a; }
/* 곧 위험한 일 - 주황. 굵게. */
.log .warn { border-left-color: #ff9020; color: #ffbb66; font-weight: 700;
             background: rgba(255, 150, 30, .08); }
/* 사람이 한 말 - 흰색. 유일하게 순백이라 눈에 걸린다. */
.log .say  { border-left-color: #6ad4ff; color: #ffffff; }
/* 시스템·명령 결과 - 흐리게 죽인다. 이게 있어야 위의 것들이 튄다. */
.log .sys  { border-left-color: #3a3a52; color: #6a6a86; font-size: 12px; }

/* 같은 말이 반복된 횟수 */
.log .rep {
    font-style: normal;
    font-size: 11px;
    margin-left: 6px;
    padding: 0 4px;
    color: #0a0a12;
    background: #7a7a96;
}

/* ── 로그 탭 ── */
.log-tabs {
    display: flex;
    gap: 4px;
    flex: 0 0 auto;
}

.log-tab {
    width: auto;
    margin: 0;
    padding: 3px 12px;
    font-size: 12px;
    background: #14141f;
    border: 2px solid #2a2a3e;
    color: #6a6a8a;
}

.log-tab.on {
    background: #2a2a3e;
    border-color: #6ad4ff;
    color: #d8d8ea;
}

.chat {
    display: flex;
    gap: 6px;
}

.chat button {
    flex-shrink: 0;
}

/* 방향 버튼: PC 에서는 방향키/WASD 로 충분하므로 숨긴다.
   폰처럼 좁은 화면에서만, 게임 화면 위에 겹쳐서 나타난다.
   (아래로 쌓으면 가뜩이나 좁은 세로 공간을 100px 넘게 잡아먹는다) */
/* PC 에서는 방향키를 쓰므로 아예 안 보인다.
   dock-hands 는 PC 에서 '없는 셈' 이라 데스크톱 배치가 그대로 유지된다. */
.dock-hands {
    display: contents;
}
.dpad {
    display: none;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    flex: 0 0 auto;
}

.dpad-mid {
    display: flex;
    gap: 42px;
}

.dpad button {
    width: 46px;
    height: 40px;
    font-size: 15px;
    background: #1e1e2ecc;
    border-color: #55557a;
    /* ★ 꾹 누르고 있어야 계속 걷는 버튼이다.
       이 세 줄이 없으면 누른 채로 손이 조금만 움직여도 화면이 스크롤되거나
       글자가 선택돼서, 걷다가 조작이 끊긴다. */
    touch-action: none;
    user-select: none;
    -webkit-user-select: none;
    -webkit-tap-highlight-color: transparent;
}

.dpad button:active {
    background: #4a4a68;
}

/* 폰 화면 : 위아래로 쌓는다 (게임 화면이 위, 로그가 아래) */
/* ─────────────────────────────────────────────
   폰에서 꾹 눌렀을 때 뜨는 브라우저 메뉴 막기

   ★ 웹페이지라서 생기는 문제다.
     브라우저는 이게 '게임 버튼' 인지 '문서' 인지 모른다. 그래서 길게 누르면
     복사·공유·이미지 저장 메뉴를 띄운다. 아이템 아이콘이 <img> 라서 특히 잘 걸린다.
     스킬을 꾹 눌러 쓰려는데 저장 메뉴가 뜨면 게임이 아니라 웹사이트가 된다.

   ★ 단, 로그와 입력칸은 일부러 예외로 둔다.
     남이 한 말이나 아이템 이름을 복사하고 싶을 때가 있다.
     전부 막으면 그건 그냥 불편한 것이다.
   ───────────────────────────────────────────── */
#game,
.modal {
    -webkit-touch-callout: none;    /* 길게 눌러도 메뉴가 안 뜬다 */
    -webkit-user-select: none;
    user-select: none;
    /* 두 번 눌러 확대되는 것을 막는다. 밀어서 넘기는 것(퀵슬롯·로그)은 그대로 된다.
       덤으로 폰의 '누른 뒤 300ms 기다림' 이 사라져서 반응이 빨라진다. */
    touch-action: manipulation;
}

/* 여기서는 글을 고르고 복사할 수 있어야 한다 */
.log,
.tooltip,
input,
textarea {
    -webkit-touch-callout: default;
    -webkit-user-select: text;
    user-select: text;
}

/* 아이콘은 장식이다. 누름은 칸(부모)이 받는다.
   <img> 를 길게 누르면 '이미지 저장' 이 뜨는데, 이 두 줄로 사라진다.
   (툴팁도 아이콘이 아니라 칸에 붙어 있어서 잃는 기능이 없다) */
img.icon {
    -webkit-user-drag: none;
    pointer-events: none;
}

@media (max-width: 820px) {
    #game {
        padding: 5px;
        gap: 5px;
    }

    .main-row {
        flex-direction: column;
        gap: 5px;
    }

    /* 게임 화면이 위쪽 대부분을 차지한다 */
    .stage {
        flex: 1 1 auto;
        min-height: 0;
        width: 100%;
    }

    /* 로그는 아래에 조금만. 게임 화면을 최대한 남겨둔다. */
    .side {
        flex: 0 0 auto;
        width: 100%;
    }

    .log {
        flex: 0 0 auto;
        height: 92px;
        font-size: 12px;
        line-height: 1.45;
    }

    /* 아래쪽 줄들을 얇게 (세로가 귀하다) */
    .quickbar {
        gap: 3px;
    }

    .zonebar {
        font-size: 12px;
        padding: 3px 6px;
    }

    /* ★ 폰에는 키보드가 없으므로 방향 버튼을 보여준다.
       왼쪽 = 이동 / 오른쪽 = 공격. 두 엄지가 각자 맡는다. */
    .dock-hands {
        display: flex;
        align-items: center;
        gap: 6px;
    }

    .dpad {
        display: flex;
    }

    /* 십자 모양을 좀 더 촘촘하게. 옆칸(스킬)에 폭을 넘겨준다 */
    .dpad-mid { gap: 34px; }
    .dpad button {
        width: 42px;
        height: 36px;
        background: #1e1e2e;
    }

    /* ★ 퀵슬롯은 접지 말고 옆으로 민다.
       방향키가 폭을 가져가서, 접히게 두면 3~4줄이 되어 게임 화면을 잡아먹는다.
       한 줄로 고정하고 넘치는 건 손가락으로 밀어서 본다. */
    .bars .quickbar {
        flex-wrap: nowrap;
        overflow-x: auto;
        overflow-y: hidden;
        justify-content: flex-start;
        scrollbar-width: none;
    }

    /* 좁으면 아래 조작부를 위아래로 쌓는다.
       나란히 두면 퀵슬롯이 4줄로 접혀서 게임 화면을 다 잡아먹는다. */
    .dock {
        flex-direction: column;
        gap: 5px;
    }

    /* 체력·마나를 가로로 눕힌다 (세로가 귀하다) */
    .vitals {
        flex: 0 0 auto;
        flex-direction: row;
        align-items: center;
        gap: 8px;
        padding: 5px 8px;
    }

    /* 게이지는 최소 너비를 지킨다.
       0 으로 두면 상태칸이 늘어날 때 HP/MP 바가 통째로 찌그러졌다. */
    .vitals .st-gauge { min-width: 76px; }

    /* 가로 배치에서는 상태칸이 남는 폭만 쓰고, 넘치면 옆으로 스크롤한다 */
    .vitals .st-status { flex: 1 1 0; }

    .bar.big { height: 12px; }

    /* 슬롯을 줄여 한 줄에 들어가게 */
    .qslot {
        width: 34px;
        height: 34px;
        border-width: 2px;
    }

    /* 한 줄로 유지한다. 두 줄이 되면 그만큼 게임 화면이 줄어든다. */
    .statline {
        flex-wrap: nowrap;
        gap: 7px;
        font-size: 11px;
        overflow-x: auto;
        white-space: nowrap;
    }

    .statline .st-gauge { min-width: 34px; }

    /* 창 버튼은 글자만 (단축키 표시는 키보드 없는 기기에서 무의미) */
    .zonebar-btns .hud-btn { padding: 3px 6px; font-size: 11px; }
    .zonebar-btns .hud-btn b { display: none; }

    .bag-body {
        flex-direction: column;
    }

    .equip-col {
        width: 100%;
    }

    .qslot {
        width: 40px;
        height: 40px;
    }
}

/* ── 버프·상태이상 표시 ──────────────────────
   ★ 자리를 항상 잡아둔다.
     전에는 비어 있을 때 display:none 이었고 여러 줄로 늘어나기까지 해서,
     버프가 하나 붙는 순간 이 칸이 37px 커졌다.
     그만큼 게임 화면이 줄어들어서 **싸우는 도중에 화면이 튀었다.**

     그래서 두 가지를 건다.
       1) 높이 고정 — 비어 있어도 자리를 지킨다 (안 그러면 생길 때 밀린다)
       2) 줄바꿈 금지 + 가로 스크롤 — 많아져도 세로로 안 늘어난다
   ─────────────────────────────────────────── */
.st-status {
    display: flex;
    gap: 4px;
    align-items: center;
    flex: 0 0 22px;          /* 세로 배치에서 높이 고정 */
    height: 22px;            /* 내용이 바뀌어도 절대 안 변한다 */
    min-width: 0;            /* 가로 배치에서 옆칸을 밀어내지 않게 */
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;   /* 얇은 칸이라 스크롤바는 숨긴다 */
}

.st-status::-webkit-scrollbar { height: 0; }
.st-eff { flex: 0 0 auto; }
.st-eff {
    display: inline-flex; align-items: center; gap: 2px;
    font-style: normal; font-size: 12px; font-weight: 700;
    padding: 1px 5px; border: 1px solid; border-radius: 9px;
    background: rgba(10, 10, 18, .7);
    animation: effPulse 1.1s ease-in-out infinite;
}
.st-eff b { font-size: 10px; opacity: .75; }
@keyframes effPulse { 0%,100% { opacity: 1 } 50% { opacity: .55 } }







/* ── GM 패널 ──────────────────────────────────
   ★ 명령 25가지에 인자까지 외워서 치는 건 사람이 할 일이 아니다.
     전부 눌러서 고르게 한다. 목록은 서버가 실제 데이터에서 뽑아 보낸다.
   ─────────────────────────────────────────── */
.gm-body {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 10px;
    min-height: 0;
}

.gm-search {
    width: 100%;
    margin: 0;
    padding: 7px 10px;
    font-size: 13px;
    background: #0a0a12;
    border: 2px solid #3a3a52;
    color: #d8d8ea;
}

.gm-search:focus { border-color: #6ad4ff; outline: none; }

.gm-cats { display: flex; gap: 4px; flex-wrap: wrap; }

.gm-cat {
    width: auto; margin: 0;
    padding: 4px 12px;
    font-size: 12px;
    background: #14141f;
    border: 2px solid #2a2a3e;
    color: #7a7a96;
}

.gm-cat.on { background: #2a2a3e; border-color: #6ad4ff; color: #d8d8ea; }

.gm-list {
    display: flex;
    flex-direction: column;
    gap: 4px;
    overflow-y: auto;
    max-height: 52vh;
    scrollbar-width: thin;
    scrollbar-color: #3a3a52 #0a0a12;
}

/* 명령 하나 = 이름 / 실제 명령 / 설명 세 줄 */
.gm-cmd {
    width: 100%; margin: 0;
    display: grid;
    grid-template-columns: minmax(110px, 0.9fr) minmax(140px, 1.1fr) 2fr;
    gap: 10px;
    align-items: center;
    text-align: left;
    padding: 7px 10px;
    background: #14141f;
    border: 2px solid #2a2a3e;
}

.gm-cmd:hover { border-color: #6ad4ff; background: #1e1e2e; }

.gm-name { color: #d8d8ea; font-size: 13px; }
/* 실제로 치는 명령을 같이 보여준다. 쓰다 보면 저절로 외워진다. */
.gm-cmdline { color: #7a7a96; font-size: 11px; }
.gm-desc { color: #6a6a8a; font-size: 11px; }

.gm-head {
    padding: 6px 2px;
    font-size: 13px;
    color: #7a7a96;
}

.gm-head b { color: #ffc857; margin-left: 6px; }

.gm-back {
    width: auto; margin: 0 0 4px;
    padding: 3px 10px;
    font-size: 12px;
    background: #14141f;
    border: 2px solid #2a2a3e;
    color: #9be564;
}

/* 고를 값들 - 몬스터 17종, 아이템 44종이 여기 깔린다 */
.gm-picks { display: flex; flex-wrap: wrap; gap: 4px; }

.gm-pick {
    width: auto; margin: 0;
    padding: 5px 11px;
    font-size: 12px;
    background: #1e1e2e;
    border: 2px solid #3a3a52;
    color: #c8c8dc;
}

.gm-pick:hover { border-color: #ffc857; color: #ffd98a; }

.gm-num { display: flex; gap: 6px; margin-top: 8px; }

.gm-num input {
    width: 110px; margin: 0;
    padding: 5px 8px;
    background: #0a0a12;
    border: 2px solid #3a3a52;
    color: #d8d8ea;
}

/* ── 로그에 적힌 명령 (눌러서 실행) ──
   도움말도 오류 문구도 이미 명령을 적어 준다. 그걸 그대로 누르게 만든다. */
.cmdchip {
    font-weight: normal;
    cursor: pointer;
    padding: 0 4px;
    border-bottom: 1px dashed #6ad4ff;
    color: #6ad4ff;
}

.cmdchip:hover { background: #2a2a3e; color: #a8e8ff; }

/* 자기 강화(good)와 상태이상(bad) 을 눈으로 갈라준다.
   ★ 색만으로는 "지금 내가 유리한가"가 안 읽힌다. 모양을 다르게 한다. */
.st-eff.good { border-style: solid; border-width: 2px; }
.st-eff.bad  { border-style: dashed; }
.st-eff.good::before { content: '▲'; font-size: 8px; opacity: .7; margin-right: 1px; }
.st-eff.bad::before  { content: '▼'; font-size: 8px; opacity: .7; margin-right: 1px; }



/* 깎이는 옵션 (무거운 도끼의 회피 등).
   ★ '+3' 과 '-3' 을 같은 색으로 쓰면 포기하는 것이 눈에 안 들어온다. */
.minus { color: #ff8a8a; }
