﻿/* =============================================
   GMS 계산기 — style.css  (묶음1: 청록 다크 테마 + 폰트)
   ============================================= */

/* ── @font-face ── */
/* 2026-09-01에 '고딕'을 Pretendard로 갈아끼웠다가, 예전 서체가 더 낫다는
   피드백으로 원래 파일(ONE_Mobile_Title.ttf)로 되돌림. Pretendard 파일
   자체는 font/PretendardVariable.woff2에 남겨뒀다 — 나중에 다시 쓸 수도
   있으니 지우지 않음. */
@font-face {
  font-family: '고딕';
  src: url('font/ONE_Mobile_Title.ttf') format('truetype');
  font-weight: normal; font-style: normal;
}
@font-face {
  font-family: 'Maple';
  src: url('font/Maple.ttf') format('truetype');
  font-weight: normal; font-style: normal;
}
/* 가변 폰트 한 파일에 일반과 Bold가 모두 들어 있다. font-weight 값에 따라 굵기가 실제 글꼴로 나온다. */
@font-face {
  font-family: 'Pretendard';
  src: url('font/PretendardVariable.woff2') format('woff2-variations');
  font-weight: 45 920; font-style: normal;
}
/* 홈 제목 스티커 글자 전용. 메이플스토리 Bold, 1.4MB의 font/Maple.ttf에서 별·님·앱 세 글자만 뽑은 2KB 글꼴이다.
   제목 글자를 바꾸면 다시 뽑아야 한다 */
@font-face {
  font-family: 'MapleTitle';
  src: url('font/maple_home.woff') format('woff');
  font-weight: normal; font-style: normal; font-display: block;
}
@font-face {
  font-family: '8bit';
  src: url('font/8bit.ttf') format('truetype');
  font-weight: normal; font-style: normal;
}

/* ── CSS 변수 ── */
*,*::before,*::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
  /* 브라우저가 직접 그리는 것들(select 펼침 목록, 스크롤바, 기본 폼 위젯)이
     테마를 따라가게 한다. 이게 없으면 다크 모드에서도 흰 위젯이 나온다. */
  color-scheme: dark;

  /* 홈 화면에 추가해서 실행하면(PWA standalone) 상태바·홈 인디케이터 밑까지
     화면이 넓어져서 그대로 두면 헤더가 시계에 가린다. 그만큼을 띄우는 값.
     브라우저 탭에서 열거나 노치가 없는 기기면 env()가 0이라 아무 영향이 없다. */
  --safe-top:    env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);

  /* 상단 고정 영역 높이. 사이드바/콘텐츠가 "헤더 아래"에 붙는 기준값이다.
     헤더 밑에 띠를 하나 더 깔게 되면 --top-h에 그 높이만 더하면 된다.
     --top-h가 안전영역을 포함하므로 이걸 쓰는 사이드바 등은 자동으로 따라온다. */
  --hdr-h:  60px;
  --top-h:  calc(var(--hdr-h) + var(--safe-top));

  /* 배경 — 우주 다크 톤 (보라 채도 낮춤) */
  --bg:      #08060d;
  --bg2:     #100e1b;
  --bg3:     #181523;
  --bg-card: #121019;
  --bg-hover:#201e2f;

  /* 텍스트 */
  --text:     #ffffff;
  --text-sub: rgba(255,255,255,.72);
  --text-dim: rgba(255,255,255,.42);

  /* 테두리 */
  --border:   rgba(var(--hue),.2);
  --border-hl:rgba(var(--hue-l),.45);

  /* 그림자 */
  --shadow:    0 2px 8px rgba(0,0,0,.4);
  --shadow-md: 0 6px 24px rgba(0,0,0,.55);
  --shadow-lg: 0 16px 48px rgba(0,0,0,.7);

  /* 메인 그라데이션 — 우주 보라 (채도 낮춤) */
  --grad:       linear-gradient(135deg,#40315c 0%,#231c3a 100%);
  --grad-card:  linear-gradient(160deg,#181521 0%,#0f0d1b 100%);

  /* 포인트 컬러 — 글자에 쓰는 라벤더·금색은 원래의 진한 값이다.
     한때 다크 채도를 낮추며 이 둘도 낮췄더니 금색 숫자·제목 글자가 연해 보여 되돌렸다.
     채도를 낮춘 것은 배경·테두리에 쓰는 아래 --hue 셋뿐이다 */
  --primary:   #ae9aeb;   /* 라벤더 */
  --primary-d: #8355d2;
  --primary-l: rgba(var(--hue-l),.12);
  /* 별빛 골드 원본값. CSS 곳곳의 금색이 이 값 하나를 따른다 */
  --star:      246,199,68;
  --accent:    rgb(var(--star));
  --gold:      #d8b15a;
  --danger:    #f05060;
  --danger-l:  rgba(240,80,96,.14);
  --success:   #3dd68c;
  --success-l: rgba(61,214,140,.12);

  /* 반경 */
  --radius-sm:  4px;
  --radius:     6px;
  --radius-lg:  8px;
  --radius-pill:999px;

  /* 카드·패널의 반투명 바탕 (보라 채도 낮춤) */
  --panel-veil: rgba(18,15,27,.7);

  /* 포인트 색 원본값 — 테마별로 이 셋만 바꾸면 하드코딩돼 있던 곳까지 따라온다 (채도 낮춤) */
  /* 채도를 낮췄다 — 원래 147,113,225 / 174,154,235 / 131,85,210은 다크 바탕에서 너무 진하다는 의견 */
  --hue:   154,130,208;
  --hue-l: 180,166,223;
  --hue-d: 136,104,191;

  /* var(--grad) 배경 위에 얹는 글자색. 다크에서는 어두운 보라 배경에 금색 글자가
     맞지만, 라이트에서는 --grad 자체가 골드 계열이라 --accent(역시 골드)를
     쓰면 금색 위에 금색 글자가 된다. 배경과 독립적으로 테마별로 정한다. */
  --on-grad: var(--accent);
  /* 버튼·선택된 탭 바탕. 그라데이션 없이 한 색으로 칠한다 */
  --btn:        #45365f;
  --btn-hover:  #524172;
  --on-btn:     var(--accent);
  --btn-border: rgba(var(--hue-l),.25);
  --btn-shadow: 0 2px 6px rgba(0,0,0,.3);
  --lookup-bg: rgba(86,48,115,.12);

  /* 등급 색은 한 곳에서만 정한다. --g-*는 테두리·배경용 원색,
     --gt-*는 글자용. 화이트 테마에서 노랑(#ffcc00)·연두(#ccff00)를 밝은 바탕에
     그대로 쓰면 대비가 1.3~1.7까지 떨어져 글자가 사실상 안 보인다.
     그래서 글자에만 같은 색상의 어두운 변형을 따로 둔다. */
  --g-rare: #6699ff;  --g-epic: #b978ff;  --g-unique: #ffcc00;  --g-legendary: #ccff00;
  --gt-rare: #6699ff; --gt-epic: #b978ff; --gt-unique: #ffcc00; --gt-legendary: #ccff00;
}

/* ═══ 화이트 테마 ═══
   색은 대부분 위 변수를 거쳐 쓰이므로 변수만 갈아끼우면 대부분 따라온다.
   변수를 안 거치고 rgba(255,255,255,.0x)로 박아둔 곳들은 흰 배경에서
   보이지 않게 되므로 아래에서 따로 어두운 톤으로 덮는다. */
:root[data-theme="light"] {
  color-scheme: light;   /* 브라우저 기본 위젯도 라이트로 (다크의 color-scheme 상쇄) */

  /* 다크가 보라 계열이니 라이트는 노랑/골드 계열로 간다.
     배경은 연보라 대신 흰색·따뜻한 아이보리, 선은 골드. */
  --bg:      #ffffff;
  --bg2:     #ffffff;
  --bg3:     #fbf6e6;
  --bg-card: #ffffff;
  --bg-hover:#fdf4dd;

  --text:     #14121c;
  --text-sub: rgba(20,18,28,.82);
  --text-dim: rgba(20,18,28,.82);

  --border:   rgba(184,134,11,.34);
  --border-hl:rgba(184,134,11,.60);

  --shadow:    0 2px 8px rgba(120,95,20,.10);
  --shadow-md: 0 6px 24px rgba(120,95,20,.14);
  --shadow-lg: 0 16px 48px rgba(120,95,20,.18);

  --grad:       linear-gradient(135deg,#e0a92b 0%,#b8860b 100%);
  --grad-card:  linear-gradient(160deg,#ffffff 0%,#fffdf6 100%);

  /* 흰 배경 위에서 흰 글씨가 읽히도록 충분히 어두운 골드 */
  --primary:   #a97b0d;
  --primary-d: #8a6309;
  --primary-l: rgba(184,134,11,.13);
  --accent:    #9a6f12;
  --gold:      #8f6a1c;
  --danger:    #d02236;
  --danger-l:  rgba(208,34,54,.10);
  --success:   #0f7a48;
  --success-l: rgba(15,122,72,.12);
  --panel-veil: rgba(255,255,255,.86);
  --star:  246,199,68;
  --hue:   184,134,11;
  --hue-l: 214,168,44;
  --hue-d: 138,99,9;
  --on-grad: #ffffff;
  /* 라이트의 아이덴티티는 노랑이다. 골드 그라데이션이 황토색처럼 칙칙하다는 의견으로,
     그라데이션을 빼고 밝은 노랑 한 색에 검은 글자로 칠한다. 갈색 기운이 도는 골드는 쓰지 않는다 */
  --btn:        rgb(var(--star));
  --btn-hover:  #efba2c;
  --on-btn:     var(--text);
  --btn-border: #e3ad24;   /* 다크처럼 얇은 테두리. 바탕보다 한 단계 짙은 노랑 */
  --btn-shadow: 0 2px 6px rgba(214,160,20,.22);
  --lookup-bg: #ffffff;
  --gt-rare: #2f5fd0; --gt-epic: #7c34d6; --gt-unique: #8a6b00; --gt-legendary: #566f00;
}

/* 로고 그라디언트는 라이트에서도 그대로 둔다(사용자 요청) */
/* 스크롤바도 보라 → 골드 */
:root[data-theme="light"] ::-webkit-scrollbar-thumb { background: rgba(184,134,11,.42); }

/* 변수 밖에 하드코딩돼 있어 화이트에서 안 보이던 것들 */
/* 헤더·사이드바 배경은 변수가 아니라 그라디언트를 직접 써서 여기서 따로 덮는다 */
:root[data-theme="light"] .header {
  background: linear-gradient(180deg, rgba(255,255,255,.92), rgba(246,244,251,.86));
  border-bottom: 1px solid var(--border);
}
:root[data-theme="light"] .sidebar {
  background: linear-gradient(180deg, rgba(255,255,255,.92), rgba(244,242,250,.86));
  border-right: 1px solid var(--border);
}
:root[data-theme="light"] .ccbtn--del { background: rgba(208,34,54,.12); }
:root[data-theme="light"] .sb-nav__item:hover { background: rgba(20,18,28,.06); }
:root[data-theme="light"] .ccbtn--edit        { background: rgba(20,18,28,.07); }
:root[data-theme="light"] .crystal-bar__track { background: rgba(20,18,28,.09); }
:root[data-theme="light"] .lib-progress       { background: rgba(20,18,28,.09); }
:root[data-theme="light"] .sf-bidir           { background: rgba(20,18,28,.04); }
/* 화이트 모드 헤더 버튼(로그인·설정) — 안을 채우던 골드 그라디언트가 촌스럽다는
   피드백으로 완전히 투명하게 비우고 테두리만 남겼다. 글자는 검은색.
   테두리 색 계열(--hue-l, 골드)은 기존과 동일 — 채움이 없어진 만큼 알아보기
   쉽게 진하기만 올렸다. 다크 모드 쪽(.hbtn 기본 규칙)은 손대지 않았다. */
:root[data-theme="light"] .hbtn {
  background: transparent;
  color: var(--text);
  border-color: rgba(var(--hue-l),.55);
}
:root[data-theme="light"] .hbtn:hover { background: rgba(var(--hue-l),.08); border-color: rgba(var(--hue-l),.8); color: var(--text); }
:root[data-theme="light"] #headerBtnSettings { color: var(--text); }
/* 다크용으로 고른 밝은 파랑/보라/빨강이 흰 배경에서는 대비가 부족하다.
   색 계열은 그대로 두고 명도만 낮춘 값으로 덮는다. */
:root[data-theme="light"] .hexa-result-row .rv.hp-suf { color: #0369a1; }
:root[data-theme="light"] .bhp-tr__dot--5             { color: #1d4ed8; }
:root[data-theme="light"] .force-arc                  { color: #1d4ed8; }
:root[data-theme="light"] .force-auth                 { color: #6d28d9; }
/* select 화살표가 흰색으로 박혀 있어 흰 배경에서 안 보인다 → 어두운 화살표로 교체 */
:root[data-theme="light"] .bhp-diff-sel {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='5' viewBox='0 0 9 5'%3E%3Cpath d='M0 0l4.5 5L9 0z' fill='%2314121c88'/%3E%3C/svg%3E");
}
:root[data-theme="light"] .empty,
:root[data-theme="light"] .ci-empty,
:root[data-theme="light"] .bus-empty          { color: var(--text-dim); }

/* ── 기본 ── */
/* 배경 층(body::before·::after, 아래 움직임 효과)보다 위에 오게 한다 */
.header, .app, .overlay { position: relative; z-index: 1; }

/* 세로 스크롤바가 생겼다 사라졌다 하면 그만큼 본문 폭이 늘었다 줄었다 해서
   화면이 좌우로 밀린다(패밀리어 등급업 기록이 길어질 때 특히 눈에 띄었다).
   스크롤바 자리를 항상 예약해두면 나타나도 폭이 안 변한다. */
html { font-size: 17px; scrollbar-gutter: stable; }
body {
  font-family: '고딕', 'Segoe UI', 'Malgun Gothic', sans-serif;
  /* 모눈종이 — 로딩 화면과 같은 44px 격자를 아주 옅게. 움직이지 않는 배경이라 비용이 없다 */
  background:
    linear-gradient(rgba(var(--hue-l),.08) 1px, transparent 1px) 0 0 / 44px 44px,
    linear-gradient(90deg, rgba(var(--hue-l),.08) 1px, transparent 1px) 0 0 / 44px 44px,
    var(--bg);
  background-attachment: fixed;
  color: var(--text);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  line-height: 1.55;
  /* 한글이 글자 단위로 끊기지 않고 띄어쓰기에서만 줄을 바꾼다. 칸보다 긴 한 낱말만 어쩔 수 없을 때 끊는다 */
  word-break: keep-all; overflow-wrap: break-word;
}
ul { list-style: none; }
/* 우클릭 저장 방지(app.js)와 짝을 맞춰 드래그로 빼가는 것도 막는다.
   -webkit-touch-callout은 아이폰에서 길게 눌러 저장하는 걸 막는다. */
img { display: block; -webkit-user-drag: none; -webkit-touch-callout: none; }
button { cursor: var(--cur-pointer); border: none; background: none; font: inherit; color: inherit; }

/* ── 전용 커서 ──
   뮤즈대시와 같은 방식이다. 커서 그림은 CSS로만 정하고 OS가 직접 그리게 해서 페이지 렌더링과 따로 논다.
   - 기본 커서는 body에 한 번만 걸고 아래 요소들이 물려받는다. 예전처럼 body *로 모든 요소에 하나하나 걸지 않는다.
   - 누를 수 있는 곳은 시스템 손가락 대신 var(--cur-pointer)를 쓴다. 지금은 기본과 같은 그림이고,
     손가락용 그림이 생기면 이 변수만 바꾸면 된다. 새 CSS도 손가락 커서는 이 변수로 쓴다.
   - 그림은 images/icons/cursor.png, corsor.gif 첫 프레임으로 만든 것. 원본은 화살표가 왼쪽·위 끝에 붙어
     흰 테두리가 잘려 있어서 한 칸 넓혀 그 자리만 흰색으로 채우고, 39×37을 도트 그대로 2배 한 78×74다.
     핫스팟 1 1은 왼쪽 위 화살표 끝이다. 예전 cursor32.png는 원본을 32×30으로 줄여 그림이 뭉개졌었다.
   - gif는 커서로 쓰면 첫 프레임만 나온다. 움직이게 하려고 JS로 그림을 마우스에 붙이면 mousemove마다 다시 그려 렉이 생긴다.
   - 끝의 default·pointer 폴백을 빼면 규칙 자체가 무효가 된다.
   - 크롬은 32px보다 큰 커서를 그림 전체가 화면 안에 들어올 때만 그리고, 화면 오른쪽·아래 끝에서는 기본 커서로 바꾼다.
     32px로 줄여 보니 너무 작아서, 끝에서는 기본 마우스로 바뀌는 것을 받아들이고 큰 그림을 쓴다. 뮤즈대시 64px 커서도 같다 */
:root {
  --cur-default: url('images/icons/cursor.png?v=20261027e') 1 1, default;
  --cur-pointer: url('images/icons/cursor.png?v=20261027e') 1 1, pointer;
}
body { cursor: var(--cur-default); }
a:any-link { cursor: var(--cur-pointer); }
/* 브라우저 기본 스타일이 선택 목록·라벨·체크박스 등에 시스템 화살표를 따로 걸어 두므로 부모 커서를 다시 물려받게 한다.
   눌리는 라벨 안의 체크박스는 손가락, 나머지는 기본 전용 커서가 된다 */
select, option, optgroup, label, input { cursor: inherit; }
/* 글자 입력칸은 I빔을 그대로 쓴다. 물려받은 커서가 I빔을 덮지 않게 다시 건다 */
input:not([type]), input[type="text"], input[type="number"], input[type="search"], input[type="email"], input[type="password"],
textarea, [contenteditable="true"] { cursor: text; }

/* ── 마우스 효과 ──
   커서 별 꼬리: common.js cursorTrail이 별을 만들고 TRAIL_LIFE_MS 뒤 지운다. 길이도 거기서 정한다.
   색은 커서 그림의 버섯처럼 파스텔 넷. 별을 만들지 않는 조건은 JS에서 본다 */
.fx-trail {
  --trail-1: rgb(var(--star)); --trail-2: #f7a8cf; --trail-3: #9fd8f5; --trail-4: #c9b8f5;
  position: fixed; inset: 0; z-index: 3500; pointer-events: none; overflow: hidden; contain: strict;
}
:root[data-theme="light"] .fx-trail { --trail-2: #f28bbd; --trail-3: #6cc2ec; --trail-4: #f0b72a; }
.fx-trail i {
  position: absolute; left: 0; top: 0; width: var(--s); height: var(--s); margin: calc(var(--s) / -2) 0 0 calc(var(--s) / -2);
  background: var(--c); clip-path: polygon(50% 0, 62% 38%, 100% 50%, 62% 62%, 50% 100%, 38% 62%, 0 50%, 38% 38%);
  animation: trailFall .7s ease-out forwards;
}
@keyframes trailFall {
  from { transform: translate(var(--x), var(--y)) scale(1) rotate(0deg); opacity: 1; }
  to { transform: translate(calc(var(--x) + var(--dx)), calc(var(--y) + 20px)) scale(.2) rotate(90deg); opacity: 0; }
}
::-webkit-scrollbar { width: 5px; height: 5px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(var(--hue),.3); border-radius: 99px; }
::-webkit-scrollbar-thumb:hover { background: var(--primary); }
@media (max-width: 768px) {
  ::-webkit-scrollbar { display: none; }
  * { scrollbar-width: none; -ms-overflow-style: none; }
}

/* ── HEADER ── */
.header {
  /* 안전영역만큼 위를 비우고 그만큼 키를 키운다 — 내용은 그대로 60px 안에 놓인다.
     padding을 한 줄로 쓰면 위쪽이 0으로 덮이므로 위쪽 값에 안전영역을 넣는다 */
  height: var(--top-h);
  padding: var(--safe-top) 24px 0;
  /* 글래스 — 헤더 뒤로 본문이 비치는 것은 의도된 디자인이다 */
  background: linear-gradient(180deg, rgba(18,12,38,.82), rgba(8,5,20,.72));
  backdrop-filter: blur(14px) saturate(160%);
  -webkit-backdrop-filter: blur(14px) saturate(160%);
  border-bottom: 1px solid transparent;
  border-image: linear-gradient(90deg, transparent, rgba(var(--hue-l),.5), rgba(var(--star),.35), transparent) 1;
  display: flex; align-items: center;
  gap: 20px;
  flex-shrink: 0; position: sticky; top: 0; z-index: 100;
  box-shadow: 0 1px 0 rgba(var(--star),.06), 0 4px 32px rgba(0,0,0,.7), 0 0 60px rgba(86,48,115,.15);
}
.header__logo { display: flex; align-items: center; gap: 8px; }
/* 로고 글자색 — 다크는 금색→연보라, 라이트는 원래의 밝은 노랑 #f6c744→연보라 #c4b5fd.
   라이트를 진한 금색→보라로 두면 칙칙하다는 의견이 있었다 */
.header__title {
  display: flex; flex-direction: column; gap: 1px; line-height: 1.15;
  font-size: 1rem; font-weight: 800; letter-spacing: .5px;
  background: linear-gradient(90deg, rgb(var(--star)) 0%, #cac0f2 100%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}
/* 영문 서브 표기(도메인). 한글 이름 아래 작은 둘째 줄로 놓는다.
   좁은 화면(모바일 헤더)에서 예전에 "byeolni..."처럼 잘리던 문제가 있었다 —
   그 자리에 다시 긴 글자를 얹지 않도록 여기선 숨긴다. */
.header__title-en {
  font-size: .62rem; font-weight: 700; opacity: .75; letter-spacing: .2px;
  background: linear-gradient(90deg, rgb(var(--star)) 0%, #cac0f2 100%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}
.header__title-kr { font-size: 1.14em; font-weight: 900; letter-spacing: 1px; }
:root[data-theme="light"] .header__title, :root[data-theme="light"] .header__title-en {
  background-image: linear-gradient(90deg, #f6c744 0%, #c4b5fd 100%);
}
.header__center { margin-left: auto; display: flex; align-items: center; gap: 12px; }

/* 테마 토글 — 다크/화이트 텍스트 표기 + 아이콘 없는 스위치 */
.theme-toggle-wrap { display: flex; align-items: center; gap: 7px; }
.theme-toggle__label { font-size: .74rem; font-weight: 700; color: var(--text); }
.theme-toggle {
  position: relative;
  width: 40px; height: 22px; flex: 0 0 40px;
  padding: 0; border: 1px solid var(--border-hl);
  border-radius: var(--radius-pill);
  background: var(--bg3);
  cursor: var(--cur-pointer);
  transition: background .18s ease, border-color .18s ease;
}
.theme-toggle:hover { border-color: var(--primary); }
.theme-toggle__knob {
  position: absolute; top: 2px; left: 2px;
  width: 16px; height: 16px;
  border-radius: 50%;
  background: var(--btn);
  box-shadow: var(--shadow);
  transition: transform .18s ease;
}
.theme-toggle--light { background: rgba(var(--hue),.22); }
.theme-toggle--light .theme-toggle__knob { transform: translateX(18px); }
.header__right { display: flex; gap: 6px; align-items: center; }
/* 안을 채우던 그라디언트를 없애고 테두리만 남겼다(화이트뿐 아니라 다크도 동일—
   "안에 있는 색을 없애고 투명하게" 요청은 두 테마 다 해당). 다크의 글자색(--primary)은
   그대로 두고, 라이트만 검은 글씨로 아래 :root[data-theme="light"] .hbtn에서 덮는다. */
.hbtn {
  padding: 7px 17px; border-radius: var(--radius);
  font-size: .78rem; font-weight: 800; letter-spacing: .3px;
  color: var(--primary);
  background: transparent;
  border: 1.5px solid rgba(var(--hue),.55);
  transition: background .2s, border-color .2s, color .2s, box-shadow .2s, transform .2s;
}
#headerBtnSettings { color: var(--text-sub); }
/* 로그인된 상태 — 버튼에 아이디가 뜨므로 길어질 수 있다. 잘라서 헤더를 밀지 않게 한다.
   배지가 같이 들어가므로, 좁아질 때 이름만 줄고 배지는 그대로 남게 나눠 놓는다. */
/* 닉네임은 12자까지라 데스크톱에선 22em이면 배지까지 넣어도 안 잘린다.
   좁은 화면에선 햄버거·로고를 뺀 나머지가 한계라, 둘 중 작은 쪽을 쓴다. */
#headerBtnAuth { max-width: min(22em, calc(100vw - 140px)); display: inline-flex; align-items: center; gap: 6px; overflow: hidden; white-space: nowrap; }
/* 헤더 오른쪽 버튼은 로그인 뒤 명찰과 같은 높이로 맞춘다. 명찰은 ADMIN 배지가 들어가 안쪽 여백이 달라서 높이를 박아 둔다 */
#headerBtnAuth, #headerBtnSettings { height: 32px; padding-top: 0; padding-bottom: 0; display: inline-flex; align-items: center; justify-content: center; }
.hbtn__name { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.admin-badge {
  flex: none; position: relative; overflow: hidden;
  padding: 2px 8px; border-radius: 5px;
  font-size: .62rem; font-weight: 900; letter-spacing: 1px;
  color: #3a2600;
  background: linear-gradient(135deg, #fff2bf 0%, rgb(var(--star)) 45%, #d8961c 100%);
  border: 1px solid #a8740a;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.65);
}
/* 금속 광택처럼 빛이 한 번씩 훑고 지나간다 — 작은 배지 안의 transform이라 가볍다 */
.admin-badge::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(100deg, transparent 30%, rgba(255,255,255,.8) 50%, transparent 70%);
  transform: translateX(-130%);
}
@media (prefers-reduced-motion: no-preference) {
  .admin-badge::after { animation: badgeShine 3.6s ease-in-out infinite; }
}
@keyframes badgeShine { 0%, 62% { transform: translateX(-130%); } 100% { transform: translateX(130%); } }
/* 로그인 표시는 테두리로 준다. 글자색은 라이트 테마에서 .hbtn이 더 높은 명세도로
   덮어쓰기 때문에(:root[data-theme="light"] .hbtn) 테마별로 갈리지만, 테두리는 양쪽 다 걸린다. */
.hbtn--on { border-color: rgba(var(--star),.75); }
/* 로그인하면 버튼이 명찰이 된다 — 알약 대신 둥근 사각형, 진한 금색 테두리 두 겹(바깥 테두리 + 안쪽 선) */
#headerBtnAuth.hbtn--on {
  border-radius: var(--radius); padding: 3px 12px 3px 4px; gap: 8px;
  border-width: 2px; border-color: rgb(var(--star));
  box-shadow: inset 0 0 0 1px rgba(var(--star),.35);
}
#headerBtnAuth.hbtn--on:not(:has(.admin-badge)) { padding-left: 12px; }
#headerBtnAuth.hbtn--on .hbtn__name { font-weight: 900; letter-spacing: .5px; }
:root:not([data-theme="light"]) .hbtn--on { color: var(--accent); }
/* 라이트 테마의 .hbtn 규칙이 명세도(0,3,0)로 더 높아 위 테두리를 덮는다 → 같은 급으로 다시 건다 */
:root[data-theme="light"] .hbtn--on { border-color: #f0b72a; }
/* 라이트 명찰 테두리는 황토색 골드 대신 밝은 노랑 */
:root[data-theme="light"] #headerBtnAuth.hbtn--on { border-color: #f0b72a; box-shadow: inset 0 0 0 1px rgba(var(--star),.4); }
/* 명찰 첫 줄(배지 + 닉네임). 좁아지면 이름만 줄어들게 이 줄 안에서 자른다 */
.hbtn__line { display: inline-flex; align-items: center; gap: 6px; min-width: 0; max-width: 100%; overflow: hidden; }
/* 훈장을 달면 게임처럼 닉네임 아래에 이름표가 한 줄 더 붙는다 — 그만큼 명찰이 위아래로 커진다 */
#headerBtnAuth.hbtn--medal { flex-direction: column; height: auto; min-height: 32px; padding-top: 3px; padding-bottom: 4px; gap: 2px; }
.hbtn__medal { display: block; line-height: 0; }

/* ── 훈장 이름표(medal.js) ──
   게임 그림 세 조각을 원본 크기 그대로 겹쳐 놓는다. 글꼴도 게임 이름표 크기(12px) 그대로 */
.mtag { position: relative; display: inline-block; flex: none; vertical-align: middle; }
.mtag__p { position: absolute; max-width: none; width: auto; height: auto; }
.mtag__c {
  position: absolute; background-repeat: repeat-x;
  font: 12px Arial, Dotum, "돋움", "Malgun Gothic", sans-serif; font-weight: normal; letter-spacing: 0;
  text-align: center; white-space: nowrap;
}
.cs-medal__head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.cs-medal__label { font-weight: 800; font-size: .85rem; }
.cs-medal__cur { flex: 1; min-width: 0; overflow: hidden; line-height: 0; }
.cs-medal__none { font-size: .8rem; color: var(--text-sub); line-height: normal; }
.md-pick__bar { display: flex; gap: 6px; }
.md-pick__q { flex: 1; min-width: 0; }
.md-pick__cat { flex: none; max-width: 42%; }
.md-pick__list {
  margin-top: 8px; max-height: 50vh; overflow-y: auto;
  display: flex; flex-direction: column; gap: 2px; padding: 4px;
  border-radius: 8px; background: rgba(0,0,0,.28);
}
/* 천 개 넘게 그리므로 화면 밖 줄은 그리기를 미룬다 */
.md-row {
  display: flex; align-items: center; min-height: 30px; padding: 5px 8px;
  border-radius: 6px; border: 1px solid transparent; background: transparent; cursor: pointer;
  content-visibility: auto; contain-intrinsic-size: auto 30px;
}
.md-row:hover { background: rgba(var(--hue),.14); }
.md-row.sel { border-color: rgb(var(--star)); background: rgba(var(--star),.12); }
.md-pick__empty { padding: 16px; text-align: center; font-size: .8rem; color: var(--text-sub); }
.hbtn:hover {
  background: rgba(var(--hue-d),.15);
  border-color: var(--primary);
  color: #fff;
  box-shadow: 0 0 0 3px rgba(var(--hue),.14), 0 6px 18px rgba(var(--hue-d),.22);
  transform: translateY(-1px);
}

/* ── APP ── */
/* 340px — 300px는 실제 브라우저에서 여유가 0px라 폰트 렌더링差로 줄바꿈 재발 → 여유를 크게 늘림.
   px로 고정하면 글자 크기(root font-size)를 키웠을 때 사이드바만 그대로라 긴 직업명
   ("Arch Mage (Ice, Lightning)")이 다시 줄바꿈된다 → rem으로 바꿔 글자와 같이 커지게 함.
   22.67rem × 15px = 340px 로 기존 값과 동일. */
.app { display: grid; grid-template-columns: 22.67rem 1fr; flex: 1; min-height: calc(100vh - var(--top-h));  }

/* ── SIDEBAR ── */
.sidebar {
  background: linear-gradient(180deg, rgba(14,9,30,.78), rgba(6,4,16,.7));
  backdrop-filter: blur(12px) saturate(140%);
  -webkit-backdrop-filter: blur(12px) saturate(140%);
  border-right: 1px solid rgba(var(--hue),.18);
  display: flex; flex-direction: column;
  position: sticky; top: var(--top-h);
  height: calc(100vh - var(--top-h)); overflow-y: auto;
  box-shadow: 2px 0 24px rgba(0,0,0,.4);
}
/* backdrop-filter 미지원 브라우저에서는 블러 없이 반투명 배경만 남아
   글씨가 그대로 겹쳐 읽히므로, 그 경우에만 불투명으로 되돌린다. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .header  { background: #0d0922; }
  .sidebar { background: #0b0720; }
  :root[data-theme="light"] .header  { background: #ffffff; }
  :root[data-theme="light"] .sidebar { background: #ffffff; }
}
/* 저성능·모션 축소 환경에서는 블러를 끈다 */
@media (hover:none), (max-width:768px), (prefers-reduced-motion:reduce) {
  .header, .sidebar { backdrop-filter: none; -webkit-backdrop-filter: none; }
}

/* 캐릭터 영역 */
.sb-char-area { border-bottom: 1px solid var(--border); }
.sb-char-head {
  display: flex; align-items: center;
  justify-content: space-between;
  padding: 12px 14px 8px;
}
.sb-label {
  font-size: 1.4rem; font-weight: 900;
  color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 140px;
}
.char-list { padding: 0 10px 6px; display: flex; flex-direction: column; gap: 6px; }

/* char card */
.char-card {
  position: relative;
  background: var(--panel-veil);
  border: 1px solid rgba(var(--hue),.2);
  border-radius: var(--radius);
  cursor: var(--cur-pointer); overflow: hidden;
  transition: border-color .2s;
}
/* 카드 배경 이미지(선택 사항) — 캐릭터가 cardBg를 고르면 이 <img>가 일러스트 박스
   위를 덮는다. "없음"을 고르면 이 <img> 자체가 안 그려지므로, 박스는 자기 CSS의
   기본 그라디언트만 보인다(예전엔 여기 images/icons/bg.webp가 항상 깔려 있어서
   "없음"을 골라도 그 그림이 계속 보이는 버그가 있었음 — 지금은 제거함).
   캐릭터 그림보다 아래(z-index:0)에 깔려야 하므로 일러스트는 z-index:1. */
/* 배경을 확대해서 위로 당겨봤는데(160%+anchor) 오히려 바닥이 화면 밖으로 밀려나
   더 떠 보였음(실측 확인) — 캐릭터 크기(92%) 수정만으로 이미 발이 배경 바닥에
   닿아 보여서, 배경은 단순 cover로 되돌린다. */
.portrait-bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 0; }
.char-card:hover { border-color: rgba(var(--hue-l),.4); }
/* 다크 모드의 캐릭터 카드는 불투명한 카드 색으로. 반투명 --panel-veil이면 본문 쪽 카드에는 배경의 보라 빛이 비치고
   사이드바 카드에는 사이드바 바탕이 비쳐, 같은 카드인데 색이 달라 보였다. 사이드바·홈·캐릭터 목록 카드 공통 */
:root:not([data-theme="light"]) :is(.char-card, .cg-card) { background: var(--bg-card); }
.char-card[draggable="true"] { cursor: grab; }
.char-card.active {
  border-color: #f5c842;
  box-shadow: 0 0 0 1px #f5c842;
}

/* 카드 내부: 좌=텍스트+버튼, 우=portrait */
/* flex + aspect-ratio 조합은 폭이 텍스트 칸에 밀려 정사각형이 안 나온다
   (실제로 95x130처럼 세로로 길어졌음). 오른쪽 큰 카드(.cg-card)가 쓰는 방식대로
   grid로 칼럼 폭을 고정하고, 일러스트는 그 폭의 100% + aspect-ratio로 높이를 잡는다. */
/* 112px — 캘린더 캐릭터 칩/프론티어 덱과 같은 배율(96px 원본의 1.13배)로 맞췄다. */
.char-card__inner {
  display: grid; grid-template-columns: minmax(0, 1fr) 112px;
  align-items: stretch; overflow: hidden;
}
.char-card__portrait {
  /* 정사각형(aspect-ratio) 고정을 없애고 grid align-items:stretch를 그대로 받아서
     박스 높이가 카드(텍스트 칸) 실제 높이에 꽉 차게 함 — 정사각형일 필요 없음. */
  width: 100%; height: 100%;
  background: transparent;
  display: flex; align-items: flex-end; justify-content: center;
  overflow: hidden; position: relative;
}
/* 캐릭터 그림은 배경(.portrait-bg) 위로(position·z-index) */
/* 박스가 정사각형(118x118, overflow:hidden)으로 바뀌면서 width만 130%/100%로 키우던
   예전 규칙은 height가 auto라 세로로 넘쳐서 위쪽(머리)이 잘렸다. 오른쪽 큰 카드
   (.cg-portrait)와 똑같이 width+height를 같이 %로 제한해 object-fit:contain이
   실제로 동작하게 함 — 잘리지 않고 박스 안에 꽉 차게 들어간다.
   (바닥 여백은 부모 padding-bottom이나 object-position 오프셋으로 시도했다가 둘 다
   실패함 — padding은 width/height %의 기준이 갈라져 캐릭터가 작아졌고, 3-value
   object-position("center bottom 5%")은 문법이 무효라 브라우저가 규칙 전체를
   버리고 50% 50%로 되돌아갔다(실측으로 확인). 넥슨 아바타는 96x96 정사각형이라
   object-fit:contain에 애초에 여백을 만들 레터박스가 안 생기므로 object-position은
   의미가 없었음 — margin-bottom을 이미지 자체에 줘서 크기 계산과 완전히 분리했다.) */
/* 96px 고정 — 92%(112px 기준 103px)로 두면 원본을 1.07배 늘리게 된다. */
.char-card__portrait img:not(.portrait-bg) { position: relative; z-index: 1; width: 96px; height: 96px; object-fit: contain; object-position: bottom center; margin-bottom: 4px; image-rendering: pixelated; }
.char-card__portrait--no img:not(.portrait-bg) { width: 96px; height: 96px; object-position: bottom center; margin-bottom: 4px; }
.char-card__txt {
  min-width: 0; flex: 1; display: flex; flex-direction: column;
  gap: 2px; padding: 10px 10px 8px 10px;
}
.char-card__name {
  font-size: .86rem; font-weight: 700;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  color: var(--text);
}
.char-card__lv { color: var(--accent); font-weight: 800; font-size: .73rem; }
.char-card__world-line {
  display: flex; align-items: center; gap: 3px;
  font-size: .7rem; color: var(--text-sub); font-weight: 600;
}
.char-card__world-line img { width: 20px; height: 20px; object-fit: contain; margin: -4px 0; }
/* 넘칠 땐 줄바꿈 대신 말줄임 — 줄바꿈되면 카드 높이가 튀어 레이아웃이 깨진다 */
.char-card__job-line {
  font-size: .68rem; color: var(--text-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0;
}
/* 이름 줄 오른쪽 직업 아이콘, 아래쪽 랭킹·주간 수익 — 캐릭터 목록 카드와 같은 정보 */
.char-card__top { display: flex; align-items: flex-start; justify-content: space-between; gap: 6px; min-width: 0; }
.char-card__id { min-width: 0; }
/* 레벨·서버 한 줄 */
.char-card__meta { display: flex; align-items: center; gap: 6px; min-width: 0; margin-top: 3px; }
.char-card__meta .char-card__world-line { min-width: 0; overflow: hidden; white-space: nowrap; }
.char-card__txt .hc__exp { margin-top: 4px; }
/* 수정·삭제 — 캐릭터 그림 위쪽 빈 배경에 얹는다. 사이드바 카드는 그림이 오른쪽이라 오른편, 홈 카드는 왼편.
   그림 위에서도 읽히게 반투명 어두운 바탕에 흰 글자로, 라이트 테마 규칙보다 뒤에서 한 단계 높여 덮는다 */
.char-card__portrait .char-card__btns { position: absolute; top: 6px; right: 6px; z-index: 2; margin: 0; padding: 0; gap: 4px; }
.hc__pic .char-card__btns { right: auto; left: 6px; }
.char-card .char-card__portrait .ccbtn { padding: 2px 8px; box-shadow: 0 1px 4px rgba(0,0,0,.3); }
.char-card .char-card__portrait .ccbtn--edit { background: rgba(14,10,28,.66); color: #fff; }
.char-card .char-card__portrait .ccbtn--del  { background: rgba(208,34,54,.86); color: #fff; }
.char-card .char-card__portrait .ccbtn--edit:hover { background: var(--primary); color: #000; }
.char-card .char-card__portrait .ccbtn--del:hover  { background: var(--danger); color: #fff; }
/* 마우스가 있는 기기에서는 평소 흐리게 두고 캐릭터 그림에 올리거나 키보드로 고를 때만 또렷하게.
   폰처럼 올릴 수 없는 기기는 늘 또렷하게 보인다 */
@media (hover: hover) {
  .char-card__portrait .char-card__btns { opacity: .22; transition: opacity .18s ease; }
  .char-card__portrait:hover .char-card__btns, .char-card__portrait:focus-within .char-card__btns { opacity: 1; }
}
/* 직업 일러스트는 이름 줄 안에 넣는다. 테두리·옅은 바탕은 캐릭터 목록 카드 .ci-jobicon과 같고,
   다크 모드에서도 화이트 모드의 금색 --border-hl·--primary-l 값을 그대로 쓴다 */
.char-card__jobicon { flex-shrink: 0; width: 40px; height: 40px; object-fit: contain; border-radius: 9px; border: 1px solid rgba(184,134,11,.6); background: rgba(184,134,11,.13); }
.char-card__stats { display: flex; flex-direction: column; gap: 1px; margin-top: 5px; padding-top: 5px; border-top: 1px solid var(--border); }
/* 경험치·랭킹이 없는 카드의 빈 줄 자리 app.js charCardSpacerHtml. 보이지 않게 두고 자리만 차지한다.
   랭킹 줄은 원래 통계 칸 안의 1px·홈 7px 간격 대신 바깥 간격을 받으므로 그만큼 당긴다 */
.cc-ph { visibility: hidden; }
.char-card__txt > .char-card__stat.cc-ph { margin-top: -1px; }
.hc__body > .hc__stat.cc-ph { margin-top: -7px; }
.char-card__stat { display: flex; align-items: center; justify-content: space-between; gap: 6px; font-size: .68rem; }
.char-card__stat span { color: var(--text-sub); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.char-card__stat b { flex-shrink: 0; font-weight: 900; color: var(--text); font-variant-numeric: tabular-nums; white-space: nowrap; }
.char-card__btns { display: flex; flex-direction: row; gap: 5px; margin-top: auto; padding-top: 6px; }
.ccbtn {
  padding: 3px 10px; border-radius: 6px;
  font-size: .65rem; font-weight: 800;
  transition: .12s; white-space: nowrap; text-align: center;
}
.ccbtn--edit { background: rgba(255,255,255,.08); color: var(--text-sub); }
.ccbtn--edit:hover { background: var(--primary); color: #000; }
.ccbtn--del { background: var(--danger-l); color: var(--danger); }
.ccbtn--del:hover { background: var(--danger); color: #fff; }

/* 아직 안 만든 섹션 자리 표시 */
.soon-box {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; padding: 60px 20px; text-align: center;
  background: var(--bg2); border: 1px solid var(--border); border-radius: 14px;
}
.soon-box__title { font-size: 1.05rem; font-weight: 900; color: var(--text); }
.soon-box__desc { font-size: .8rem; color: var(--text-sub); }

/* 캐릭터 목록 카드의 주간 합산 토글 — 끄면 전체 주간 합계에서 이 캐릭터가 빠진다 */
.cg-weekrow {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; margin-top: 8px; padding-top: 8px;
  border-top: 1px solid var(--border);
}
.cg-weekrow__lbl { font-size: .7rem; font-weight: 700; color: var(--text-sub); }
.cg-weektoggle {
  position: relative; display: inline-flex; align-items: center; width: 62px; height: 24px;
  border-radius: 999px; border: 1.5px solid var(--border); cursor: var(--cur-pointer); padding: 0; flex: none;
  background: var(--bg2); transition: background .15s;
}
.cg-weektoggle.on { background: rgba(var(--hue),.55); border-color: rgba(var(--hue),.55); }
.cg-weektoggle__knob {
  position: absolute; top: 1px; left: 1px; width: 20px; height: 20px; border-radius: 50%;
  background: #fff; transition: transform .15s; box-shadow: 0 1px 3px rgba(0,0,0,.3);
}
.cg-weektoggle.on .cg-weektoggle__knob { transform: translateX(38px); }
.cg-weektoggle__txt {
  position: absolute; top: 50%; transform: translateY(-50%); font-size: .6rem; font-weight: 900;
  letter-spacing: .02em; display: none;
}
.cg-weektoggle__txt--on  { left: 7px;  color: rgba(255,255,255,.85); }
.cg-weektoggle__txt--off { right: 8px; color: var(--text-sub); }
.cg-weektoggle.on  .cg-weektoggle__txt--on  { display: block; }
.cg-weektoggle.off .cg-weektoggle__txt--off { display: block; }

/* crystal bar */
.crystal-bar { padding: 8px 14px 10px; }
.crystal-bar__row { display: flex; justify-content: space-between; margin-bottom: 5px; }
.crystal-bar__detail { display: flex; gap: 10px; margin-top: 5px; }
.crystal-bar__type { display: flex; align-items: center; gap: 4px; font-size: .78rem; color: var(--text-sub); }
/* 원본이 32x38인데 14px로 그려서 44%까지 줄어 있었다. 게임에서 보던 것보다
   훨씬 작아 보인다는 지적을 받아 원본 크기에 가깝게 올린다.
   rem이라 글자 크기를 키우면 아이콘도 같이 커진다(고정 px이라 글씨만 커졌을 때
   상대적으로 더 작아 보이던 문제도 같이 해결된다). */
/* 결정석·연마석 아이콘은 게임 원본 크기 그대로 */
.crystal-icon { width: auto; height: auto; vertical-align: middle; }
.crystal-bar__label { font-size: .72rem; color: var(--text-sub); font-weight: 700; }
.crystal-bar__count { font-size: .72rem; font-weight: 800; color: var(--text); }
.crystal-bar__track {
  height: 6px; background: rgba(255,255,255,.06);
  border-radius: 99px; overflow: hidden;
  box-shadow: inset 0 1px 2px rgba(0,0,0,.4);
}
.crystal-bar__fill {
  height: 100%;
  background: linear-gradient(90deg, var(--primary), var(--accent));
  border-radius: 99px; transition: width .4s;
}

/* 전체 주간 획득 메소 */
.sb-weekmeso {
  display: flex; flex-direction: column; gap: 2px;
  margin: 0 10px 10px;
  padding: 10px 14px;
  background: linear-gradient(135deg, rgba(var(--star),.10), rgba(var(--hue),.06) 60%, transparent);
  border: 1px solid rgba(var(--star),.15);
  border-radius: 12px;
  box-shadow: 0 0 20px rgba(var(--star),.06) inset;
}
.sb-weekmeso__label { font-size: .68rem; font-weight: 700; color: var(--text-sub); }
.sb-weekmeso__note { display: block; margin-top: 2px; font-size: .62rem; font-weight: 700; color: var(--accent); }
.sb-weekmeso__val {
  font-size: 1.05rem; font-weight: 900;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 0 12px rgba(var(--star),.55);
}

/* sidebar nav */
.sb-nav {
  padding: 6px 10px 16px;
  display: flex; flex-direction: column; gap: 2px; flex: 0 0 auto;
}
.sb-nav__item {
  position: relative;
  display: flex; align-items: center; gap: 12px;
  padding: 11px 14px; border-radius: 12px;
  font-size: .88rem; font-weight: 600;
  color: var(--text-sub);
  transition: background .18s, color .18s, transform .18s;
  text-align: left; width: 100%;
}
.sb-nav__item:hover { background: rgba(255,255,255,.05); color: var(--text); transform: translateX(2px); }
.sb-nav__item.active {
  background-image: linear-gradient(90deg, rgba(var(--star),.30), rgba(var(--hue-l),.26));
  border: 1px solid rgba(var(--star),.4);
  color: var(--accent);
  box-shadow: 0 4px 16px rgba(0,0,0,.4), 0 0 12px rgba(var(--star),.08);
  text-shadow: 0 0 8px rgba(var(--star),.35);
}
/* 가장 큰 아이콘인 데스티니 무기 42×41이 원본 크기로 들어가는 상자 — 좁으면 아이콘이 그릇을 벗어나
   라벨을 밀어낸다 */
.sb-nav__icon-wrap {
  width: 42px; height: 42px; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
}
/* ── nav 아이콘 크기 ──
   그림마다 원본 픽셀 크기 그대로 보여주고, 42px 상자(.sb-nav__icon-wrap)보다
   큰 것만 줄인다. 지금은 모든 아이콘이 42px 안이라 줄어드는 그림이 없다 — 작은 원본을 억지로 키우면 도트가 뭉개져서(예: 28px→32px)
   흐려 보였던 문제 때문. width/height를 auto로 두고 max-width/max-height로만
   상한을 걸면, 상자가 고정폭이라 그 옆 글자 위치는 아이콘 크기와 무관하게
   항상 같은 자리에서 시작한다. */
.sb-nav__icon { object-fit: contain; width: auto; height: auto; max-width: 42px; max-height: 42px; transition: transform .25s cubic-bezier(.3,1.6,.5,1); }
.sb-nav__item:hover .sb-nav__icon { transform: scale(1.14) rotate(-6deg); }
.sb-nav__item.active .sb-nav__icon { filter: drop-shadow(0 0 6px rgba(var(--star),.55)); }
.sb-nav__item.active::before {
  content: ''; position: absolute; left: -1px; top: 22%; bottom: 22%; width: 3px; border-radius: 3px;
  background: linear-gradient(rgb(var(--star)), #cac0f2); box-shadow: 0 0 10px rgba(var(--star),.6);
}

/* ── CONTENT ── */
.content {
  padding: 24px;
  display: flex; flex-direction: column; gap: 0;
  background: transparent;
  min-height: calc(100vh - var(--top-h));
  min-width: 0;   /* 넓은 자식이 레이아웃을 밀지 않고 자체 스크롤하도록 */
}
.sec { display: none; flex-direction: column; gap: 16px; min-width: 0; }
.sec.active { display: flex; }

/* section header */
.sec-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
/* 제목과 본문 크기 차이가 작아 구분이 잘 안 된다는 피드백 → 제목을 키우고 아래 여백을 넓힘 */
.sec-title {
  font-size: 1.85rem; font-weight: 900; letter-spacing: -.5px; line-height: 1.25;
  position: relative; padding-left: 18px; color: var(--text);
  background: linear-gradient(90deg, #ffffff 0%, #f7e2ad 55%, #cac0f2 100%);
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}
:root[data-theme="light"] .sec-title { background-image: linear-gradient(90deg, #241a35 0%, #5b3fb0 65%, #a8740a 100%); }
.sec-title::before {
  content: ''; position: absolute; left: 0; top: 50%;
  transform: translateY(-50%);
  width: 6px; height: .88em; border-radius: 99px;
  background: linear-gradient(180deg, rgb(var(--star)) 0%, #ae9aeb 100%);
  box-shadow: 0 0 10px rgba(var(--star),.5), 0 0 20px rgba(var(--hue-l),.3);
}

/* ── CARD ── */
.card {
  background: var(--panel-veil);
  
  
  border: 1px solid rgba(var(--hue),.22);
  border-radius: var(--radius);
  padding: 20px 22px;
  box-shadow: 0 4px 24px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.05);
  position: relative; overflow: hidden; isolation: isolate;
  transition: border-color .25s, box-shadow .25s;
}
/* 위쪽 테두리에 얇은 그라디언트 띠 */
.card::after {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 2px;
  background: linear-gradient(90deg, transparent, rgba(var(--hue-l),.85), rgba(var(--star),.7), transparent);
  opacity: .55; transition: opacity .3s; z-index: 2;
}
.card:hover::after { opacity: 1; }
.card::before {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(135deg, rgba(var(--hue-l),.04) 0%, transparent 50%, rgba(var(--star),.03) 100%);
  pointer-events: none;
}
.card:hover { border-color: rgba(var(--hue-l),.38); box-shadow: 0 10px 30px rgba(0,0,0,.5), 0 0 0 1px rgba(var(--hue-l),.2), inset 0 1px 0 rgba(255,255,255,.05); }
:root[data-theme="light"] .card:hover { box-shadow: 0 12px 28px rgba(150,110,20,.14), 0 0 0 1px rgba(var(--hue-l),.3); }
.card__title {
  font-size: 1.2rem; font-weight: 800;
  text-transform: uppercase; letter-spacing: .6px;
  color: var(--text-sub); margin-bottom: 14px;
}

/* ── BOSS PANEL ── */
.boss-panel {
  display: flex; flex-direction: column; gap: 0;
  background: var(--panel-veil);
  
  
  border: 1px solid rgba(var(--hue),.2);
  border-radius: var(--radius);
  box-shadow: 0 8px 32px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.04); overflow: hidden;
}
.boss-panel__head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 20px;
  border-bottom: 1px solid rgba(var(--hue),.15);
  /* 원래는 보라기 도는 두 톤 그라디언트였는데, 색을 변수로 묶으면서 한 색이 됐다.
     테마별 포인트색을 살짝 얹어 두 톤을 되살린다. */
  background: linear-gradient(90deg, rgba(var(--hue),.12) 0%, var(--panel-veil) 100%);
}
.boss-panel__charname { font-size: .96rem; font-weight: 800; color: var(--text); }
/* 주간 합산 토글 등 딸린 것들은 전부 오른쪽 그룹에 묶어서 붙인다 —
   이름 옆에 따로 두면 좁은 화면에서 줄이 애매하게 갈린다. */
.boss-panel__headr { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; justify-content: flex-end; }
/* 캐릭터 목록 카드 안에서 쓰던 걸 여기서도 재사용한다 — 세로로 쌓이던 테두리·여백은
   여기선 가로 한 줄에 끼워 넣는 것이라 필요 없다. */
.cg-weekrow--inline { margin-top: 0; padding-top: 0; border-top: none; gap: 6px; }
.boss-crystal-count { display: flex; align-items: center; gap: 12px; }
.boss-crystal-count img { width: auto; height: auto; }
.boss-crystal-count .cc-item { display: flex; align-items: center; gap: 5px; font-size: 1.1rem; font-weight: 800; color: var(--text); }
.pill { padding: 5px 16px; border-radius: var(--radius-pill); font-size: .76rem; font-weight: 800; }
.pill--red { background: var(--danger-l); color: var(--danger); cursor: var(--cur-pointer); transition: .15s; border: 1px solid transparent; }
.pill--red:hover { background: var(--danger); color: #fff; }

/* 사이드바가 열린 중간 폭에서는 표가 래퍼보다 넓어져 바깥(overflow:hidden)에서 잘리므로 옆으로 스크롤되게 한다 */
.boss-table-wrap { background: var(--bg); overflow-x: auto; }
.boss-table { width: 100%; border-collapse: collapse; }
.boss-table thead th {
  position: sticky; top: 0; background: var(--bg2);
  padding: 10px 18px; text-align: left;
  font-size: .72rem; font-weight: 800;
  text-transform: uppercase; letter-spacing: .5px;
  color: var(--text-sub); z-index: 2;
  border-bottom: 1px solid var(--border);
}
.boss-table tbody tr { border-top: 1px solid var(--border); transition: background .12s; }
.boss-table tbody tr:first-child { border-top: none; }
.boss-table tbody tr:hover { background: var(--bg-hover); }
.boss-table tbody tr.done { background: linear-gradient(90deg, rgba(var(--star),.22), rgba(180,140,255,.22)); border-top-color: rgba(var(--star),.25); }
.boss-table tbody tr.locked { opacity: .25; }
.boss-table td { padding: 8px 18px; vertical-align: middle; color: var(--text); }

.boss-name-cell { display: flex; align-items: center; gap: 12px; }
/* title(호버 툴팁)은 모바일에서 볼 방법이 없어 탭 가능한 ⓘ를 따로 둔다 */
.bm-crystal-info {
  margin-left: auto; flex: none;
  width: 20px; height: 20px; border-radius: 50%;
  border: 1px solid var(--border); background: var(--bg2); color: var(--text-sub);
  font-size: .7rem; line-height: 1; cursor: var(--cur-pointer);
}
.bm-crystal-toggle {
  position: relative; display: inline-flex; align-items: center; width: 62px; height: 24px;
  border-radius: 999px; border: 1.5px solid var(--border); cursor: var(--cur-pointer); padding: 0; flex: none;
  background: var(--bg2); transition: background .15s;
}
.bm-crystal-toggle.on { background: rgba(var(--hue),.55); border-color: rgba(var(--hue),.55); }
.bm-crystal-toggle__knob {
  position: absolute; top: 1px; left: 1px; width: 20px; height: 20px; border-radius: 50%;
  background: #fff; transition: transform .15s; box-shadow: 0 1px 3px rgba(0,0,0,.3);
}
.bm-crystal-toggle.on .bm-crystal-toggle__knob { transform: translateX(38px); }
.bm-crystal-toggle__txt {
  position: absolute; top: 50%; transform: translateY(-50%); font-size: .6rem; font-weight: 900;
  letter-spacing: .02em; display: none;
}
.bm-crystal-toggle__txt--on { left: 7px; color: rgba(255,255,255,.85); }
.bm-crystal-toggle__txt--off { right: 8px; color: var(--text-sub); }
.bm-crystal-toggle.on .bm-crystal-toggle__txt--on { display: block; }
.bm-crystal-toggle.off .bm-crystal-toggle__txt--off { display: block; }
.boss-thumb {
  width: 44px; height: 44px; border-radius: 10px;
  background: var(--bg3); overflow: hidden;
  flex-shrink: 0; display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--border);
}
.boss-thumb img { width: 100%; height: 100%; object-fit: cover; filter: grayscale(80%) brightness(0.45); transition: filter .2s; }
tr.done .boss-thumb img { filter: none; }
.boss-label { font-size: .9rem; font-weight: 700; white-space: nowrap; color: var(--text); }

/* 난이도 필 */
.dpill {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  padding: 5px 15px; border-radius: var(--radius-pill);
  font-size: .7rem; font-weight: 900; letter-spacing: .4px;
  cursor: var(--cur-pointer); user-select: none;
  border: 2px solid transparent;
  filter: grayscale(.8) opacity(.45); transition: filter .15s;
}
.dpill:hover { filter: grayscale(.3) opacity(.85); }
.dpill.sel { filter: none; opacity: 1; box-shadow: 0 3px 12px rgba(0,0,0,.45); }
.dpill__t { display: inline-block; line-height: 1; white-space: nowrap; }
.dpill.diff-easy    { background: linear-gradient(180deg,#909098 0%,#55555e 100%); border-color:#fff; }
.dpill.diff-easy    .dpill__t { color: #fff; }
.dpill.diff-normal  { background: linear-gradient(180deg,#74e0f0 0%,#1f93b5 100%); border-color:#fff; }
.dpill.diff-normal  .dpill__t { color: #fff; }
.dpill.diff-hard    { background: linear-gradient(180deg,#f040a0 0%,#8b0050 100%); border-color:#fff; }
.dpill.diff-hard    .dpill__t { color: #fff; }
.dpill.diff-chaos   { background: linear-gradient(180deg,#37535c 0%,#15242a 100%); border-color:#e7b765; }
.dpill.diff-chaos   .dpill__t { background: linear-gradient(180deg,#ffe7a8 0%,#c8924a 100%); -webkit-background-clip:text; background-clip:text; -webkit-text-fill-color:transparent; }
.dpill.diff-extreme { background: linear-gradient(180deg,#2c1820 0%,#150b10 100%); border-color:#ff3b6e; }
.dpill.diff-extreme .dpill__t { background: linear-gradient(180deg,#ff9a3c 0%,#ff5ea8 100%); -webkit-background-clip:text; background-clip:text; -webkit-text-fill-color:transparent; }
.dpill--sm { padding: 3px 10px; font-size: .62rem; }
.dpill--sm:not(.sel) { filter: grayscale(.8) opacity(.4); }

.party-stepper {
  display: inline-flex; align-items: center;
  background: rgba(var(--hue),.08);
  border: 1.5px solid rgba(var(--hue),.25);
  border-radius: 6px; padding: 3px; gap: 3px;
  box-shadow: 0 0 10px rgba(var(--hue),.1), inset 0 1px 0 rgba(255,255,255,.05);
}
.party-stepper button {
  width: 26px; height: 26px; border-radius: 50%;
  font-size: 1rem; font-weight: 700;
  color: var(--primary);
  background: rgba(var(--hue),.12);
  border: 1px solid rgba(var(--hue),.2);
  display: flex; align-items: center; justify-content: center;
  transition: background .15s, box-shadow .15s, color .15s, border-color .15s;
}
.party-stepper button:hover:not(:disabled) {
  background: var(--primary);
  border-color: var(--primary);
  color: #000;
  box-shadow: 0 0 12px rgba(var(--hue-l),.5);
}
.party-stepper button:disabled { opacity: .2; }
.party-stepper__val { min-width: 24px; text-align: center; font-size: .88rem; font-weight: 800; color: var(--text); }
.party-dash,.rev-dash { color: var(--text-dim); font-size: .9rem; }
.rev-val { font-size: .9rem; font-weight: 800; color: var(--accent); text-shadow: 0 0 6px rgba(var(--star),.35); }

.boss-total {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 20px;
  background: var(--panel-veil);
  border-top: 1px solid rgba(var(--hue-l),.2);
}
.boss-total--month {
  background: rgba(var(--star),.04);
  border-top: 1px solid rgba(var(--star),.12);
}
.boss-total__label { font-size: .82rem; color: var(--text-sub); font-weight: 700; }
.boss-total__sub { font-size: .68rem; color: var(--text-dim); margin-left: 4px; }
.boss-total__val {
  font-size: 1.3rem; font-weight: 900;
  color: var(--accent);
  text-shadow: 0 0 12px rgba(var(--star),.4);
}
.boss-total__val--month { font-size: 1.3rem; color: rgba(var(--star),.75); text-shadow: none; }

/* ── 대여템 섹션 ── */
.rental-section {
  background: rgba(255,255,255,.02);
  border-top: 1px solid rgba(var(--hue-l),.15);
  padding: 14px 20px 12px;
}
.rental-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.rental-title { font-size: .82rem; font-weight: 800; color: var(--text-sub); }
.rental-cost-label { font-size: .82rem; font-weight: 800; color: var(--danger); }
.rental-slots { display: flex; gap: 8px; flex-wrap: wrap; }
.rental-slot {
  width: 48px; height: 48px; border-radius: 10px;
  border: 2px solid rgba(255,255,255,.12);
  overflow: hidden; position: relative;
  filter: grayscale(.85) brightness(.4);
  transition: filter .18s, border-color .18s;
}
.rental-slot.on { filter: none; border-color: rgba(var(--star),.6); }
.rental-slot img { width: 100%; height: 100%; object-fit: contain; }
.rental-footer { margin-top: 10px; display: flex; flex-direction: column; gap: 4px; }
.rental-wed-label { display: flex; align-items: center; gap: 7px; font-size: .8rem; color: var(--text-sub); font-weight: 700; }
.rental-wed-label input[type=checkbox] { accent-color: var(--primary); width: 15px; height: 15px; }
.rental-notice { font-size: .72rem; color: var(--text-dim); }

/* ── BUTTONS ── */
.hbtn:active, .sbtn:active { transform: translateY(1px) scale(.97); }
.sbtn {
  padding: 9px 20px; border-radius: 6px;
  font-size: .84rem; font-weight: 700; text-align: center;
  transition: background .18s, color .18s, filter .18s;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  border: 1px solid transparent;
}
.sbtn--add, .sbtn--primary {
  background: var(--btn); color: var(--on-btn);
  box-shadow: var(--btn-shadow);
  border-color: var(--btn-border);
}
.sbtn--add { font-size: .76rem; padding: 5px 13px; }
.sbtn--add:hover, .sbtn--primary:hover { background: var(--btn-hover); }
.sbtn--ghost {
  background: rgba(255,255,255,.06);
  color: var(--text-sub);
  border-color: var(--border);
}
.sbtn--ghost:hover { background: rgba(255,255,255,.12); color: var(--text); }
/* 라이트의 보조 버튼은 흰 바탕에 밝은 노랑 테두리. 황토색 골드 테두리는 쓰지 않는다 */
:root[data-theme="light"] .sbtn--ghost { background: #fff; border-color: rgba(var(--star),.75); color: var(--text); }
:root[data-theme="light"] .sbtn--ghost:hover { background: rgba(var(--star),.14); border-color: rgb(var(--star)); }
.sbtn--danger { background: var(--danger); color: #fff; box-shadow: 0 4px 12px rgba(240,80,96,.3); }
.sbtn--danger:hover { filter: brightness(1.1); }
.w100 { width: 100%; justify-content: center; }

/* ── FORM ── */
.field { display: flex; flex-direction: column; gap: 5px; }
.field__label { font-size: .95rem; color: var(--text-sub); font-weight: 700; }
.inp, select.sel {
  background: rgba(255,255,255,.06);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 9px 12px;
  color: var(--text); font: inherit; font-size: .86rem;
  outline: none; width: 100%;
  transition: border-color .18s, background .18s, box-shadow .18s;
  /* ★ 높이를 명시하지 않으면 컨트롤 종류마다 제 폰트 기준으로 높이를 잡아
     한 줄에 나란히 뒀을 때 서로 어긋난다(실측: date 38 / select 36 / number 40px).
     min-height로는 기준보다 큰 칸(날짜칸 42.5px)을 못 줄이므로 height로 고정한다.
     box-sizing이 border-box라 패딩·테두리를 포함한 값이다. */
  height: 40px;
}
.inp:focus, select.sel:focus {
  background: rgba(255,255,255,.1);
  border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(var(--hue-l),.12);
}
.inp[readonly] {
  opacity: .7; cursor: var(--cur-default);
  background: rgba(255,255,255,.03);
}
.inp[readonly]:focus { box-shadow: none; border-color: var(--border); }
/* 펼친 목록(option)은 OS가 그리는 영역이라 기본 흰 배경인데, select에 준 밝은
   글자색은 그대로 상속돼 다크 모드에서 흰 글씨 + 흰 배경으로 안 보였다.
   (달력 오전/오후 선택이 class="inp mc-ev__ampm"이라 기존 select.sel 규칙에 안 걸려 발생)
   select마다 규칙을 따로 다는 방식은 새 select를 추가할 때마다 또 빠뜨리게 되므로
   모든 select에 한 번에 건다. 아래 개별 규칙들은 남아 있어도 결과는 같다. */
select option { background: var(--bg2); color: var(--text); }
/* optgroup(그룹 라벨)도 같은 함정에 걸린다 — 배경을 안 주면 OS 기본 흰 배경 위에
   흰 글씨가 얹혀 라벨 줄이 통째로 흰 막대로 보인다(패밀리어 옵션의 유니크/에픽 그룹).
   라벨은 항목이 아니라 머리글이므로 글자색만 한 단계 죽여서 구분한다. */
select optgroup { background: var(--bg2); color: var(--text-sub); }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }

/* ── 빈 목록 안내 ── */
.empty { text-align: center; color: var(--text-sub); padding: 32px; font-size: .9rem; }

/* ── HEXA ── */
.hexa-layout { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.hexa-field-group { display: flex; flex-direction: column; gap: 10px; }
.hexa-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.hexa-label { display: flex; align-items: center; gap: 6px; font-size: .84rem; font-weight: 600; flex-shrink: 0; color: var(--text); }
.hexa-row .inp { max-width: 100px; }
.hexa-support-list { display: flex; flex-direction: column; gap: 8px; margin-top: 4px; }
.hexa-support-item {
  display: grid; grid-template-columns: 1fr auto auto auto auto auto;
  align-items: center; gap: 8px;
  background: var(--bg3); padding: 9px 12px; border-radius: var(--radius-sm);
}
.hexa-support-item span { font-size: .8rem; color: var(--text-sub); }
.hx-node-name { display: flex; align-items: center; gap: 6px; color: var(--text) !important; font-weight: 700; font-size: .88rem; }
.hx-node-icon { width: auto; height: auto; max-width: 40px; max-height: 40px; object-fit: contain; flex-shrink: 0; border-radius: 6px; }
/* 아이콘을 고정폭 상자에 넣어서, 보유 솔 에르다/조각 두 줄의 텍스트가 같은
   위치에서 시작하게 한다(사이드바 nav와 동일한 패턴). */
.hexa-label__icon-wrap { width: 40px; height: 40px; flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; }
.hexa-support-item .inp { max-width: 60px; }
.hexa-support-item button { color: var(--danger); font-size: .82rem; padding: 0 4px; }
/* 줄마다 밑줄이 있어서 줄 사이 간격을 두면 위쪽에만 여백이 더해져 글자가 아래로 쏠려 보인다. 간격 없이 줄 안쪽 위아래 여백만 같게 둔다 */
.hexa-result { display: flex; flex-direction: column; gap: 0; }
.hexa-result-row {
  display: flex; justify-content: space-between; align-items: center;
  padding: 12px 0; border-bottom: 1px solid var(--border);
}
.hexa-result-row:last-child { border-bottom: none; }
.hexa-result-row .rl { font-size: .86rem; color: var(--text-sub); }
.hexa-result-row .rv { font-size: .98rem; font-weight: 800; color: var(--text); display: flex; align-items: center; gap: 6px; }
.hexa-result-row .rv.ok { color: var(--accent); }
.hexa-result-row .rv.ng { color: var(--danger); }
.hexa-result-row .rv.hp-suf { color: #38bdf8; }
/* 좌측 "보유 현황" 라벨 아이콘(.hx-node-icon)과 같은 40px 상자로 맞춰서
   양쪽이 같은 크기로 보이게 한다(원본 그대로, 100%). */
.hx-res-icon { width: auto; height: auto; max-width: 40px; max-height: 40px; object-fit: contain; flex-shrink: 0; }
/* 아이콘을 값 뒤 고정폭 상자에 넣는다 — 숫자 자릿수가 달라도 아이콘(=행의 끝점)
   위치가 전부 같아진다. */
.hx-res-icon-wrap { width: 40px; height: 40px; flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; }
.hx-result-sep { margin: 14px 0 10px; border: none; border-top: 2px solid var(--border); }
/* 솔 에르다 조각 큰 그림 54×57은 위쪽 투명 여백이 8줄, 아래가 5줄이라 그림이 가운데보다 아래에 그려진다.
   그림은 그대로 두고 보이는 자리만 그 차이만큼 올린다 */
img[src*="Sol_Erda_Fragment_(Full_Size)"] { position: relative; top: -1px; }
.hexa-result-label { font-size: .78rem; font-weight: 900; color: var(--text-dim); letter-spacing: .8px; text-transform: uppercase; margin-bottom: 4px; }

/* ── LIBERATION ── */
.lib-tabs { display: flex; gap: 0; margin-bottom: 16px; border: 1.5px solid var(--border); border-radius: 12px; overflow: hidden; }
/* 무기 아이콘은 게임 원본 크기 그대로. 37×36, 42×41, 37×38로 서로 다르다 */
.lib-tab__icon { width: auto; height: auto; margin-right: 10px; flex-shrink: 0; filter: drop-shadow(0 0 6px rgba(var(--star),.6)); }
.lib-tab {
  flex: 1; display: inline-flex; align-items: center; justify-content: center;
  padding: 14px 20px; border-radius: 0;
  font-size: .95rem; font-weight: 700; line-height: 1;
  color: var(--text-sub); background: var(--bg-card);
  border: none; border-right: 1.5px solid var(--border); transition: .15s;
}
.lib-tab:last-child { border-right: none; }
/* 좁은 화면에서는 아이콘을 글자 위로 올리고 여백을 줄여 세 탭이 폭 안에 다 들어가게 한다. 아이콘은 줄이지 않는다 */
@media (max-width: 520px) {
  .lib-tab { min-width: 0; flex-direction: column; gap: 6px; padding: 10px 4px; font-size: .85rem; }
  .lib-tab__icon { margin-right: 0; }
}
.lib-tab:hover { background: rgba(var(--hue),.1); color: var(--primary); }
.lib-tab.active { background: var(--btn); color: var(--on-btn); box-shadow: none; }
.lib-panel { display: none; flex-direction: column; gap: 14px; }
.lib-panel.active { display: flex; }
.lib-progress { height: 7px; background: rgba(255,255,255,.08); border-radius: 99px; overflow: hidden; }
.lib-progress__fill { height: 100%; background: linear-gradient(90deg,var(--primary),var(--accent)); border-radius: 99px; transition: width .4s; }
.lib-pct { font-size: .74rem; color: var(--text-sub); text-align: right; margin-top: 4px; }

/* ── 시뮬레이터 공통 레이아웃 · 큐브 직작 기록 ── */
/* minmax(0,1fr) 필수 — 1fr만 쓰면 콘텐츠가 더 큰 쪽(결과 카드)이 최소폭을
   더 많이 가져가 반대쪽(토글 버튼들)이 짜부라진다 */
.sf-layout { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 16px; align-items: start; }
.sf-right { display: flex; flex-direction: column; gap: 16px; }
#sfResult { display: flex; flex-direction: column; gap: 4px; }
#cubeTabSimResult { display: flex; flex-direction: column; gap: 4px; }
#cubeTabHandrollResult { display: flex; flex-direction: column; gap: 4px; }
.hr-log-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 8px 0; border-bottom: 1px solid var(--border); font-size: .82rem; }
.hr-log-row .hr-log-icon { width: 13px; height: 13px; flex-shrink: 0; image-rendering: pixelated; }

/* 큐브 종류별 사용 개수 — 합산 없이 종류마다 아이콘 + 개수로 따로 보여준다 */
.hr-cubecount { display: flex; align-items: center; gap: 14px; }
.hr-cubecount__item { display: inline-flex; align-items: center; gap: 5px; }
.hr-cubecount__item img { width: 20px; height: 20px; object-fit: contain; }
.hr-log-row .hr-log-grade { font-weight: 700; flex-shrink: 0; }
.hr-log-row .hr-log-up { color: var(--success); font-weight: 700; flex-shrink: 0; }
.hr-log-row .hr-log-line { color: var(--text-sub); }
.hr-log-grade[data-grade="RARE"],      .hr-log-line[data-grade="RARE"]      { color: var(--gt-rare); }
.hr-log-grade[data-grade="EPIC"],      .hr-log-line[data-grade="EPIC"]      { color: var(--gt-epic); }
.hr-log-grade[data-grade="UNIQUE"],    .hr-log-line[data-grade="UNIQUE"]    { color: var(--gt-unique); }
.hr-log-grade[data-grade="LEGENDARY"], .hr-log-line[data-grade="LEGENDARY"] { color: var(--gt-legendary); }
/* 옵션 사이에 쉼표를 넣어 세 줄이 눈으로 끊어져 보이게 한다.
   마크업에 쉼표를 넣으면 줄 색(등급 색)까지 같이 물들어서 CSS로 붙인다. */
.hr-log-row .hr-log-line:not(:last-child)::after { content: ","; color: var(--text-sub); }

/* ── 불꽃 판 — 큐브와 달리 등급 색을 쓰지 않는다. 티어는 별 개수로만 보여준다 ── */
/* .pot-panel 기본값이 파일 뒤쪽에 있어 같은 특이도면 그쪽이 이긴다 — 두 클래스를 겹쳐 올린다 */
.pot-panel.flame-panel { --pot: var(--border); }
.pot-panel.flame-panel .pot-panel__head { color: var(--text); justify-content: center; }   /* 헤더에는 점수만 가운데로 */
.flame-panel__score { font-variant-numeric: tabular-nums; }

/* 한 줄 = [n추] [옵션] [점수] */
.pot-panel.flame-panel .pot-line {
  --line: var(--border); background: var(--bg2); color: var(--text); text-shadow: none;
  display: flex; align-items: center; gap: 10px; text-align: left;
}
.flame-line__rank { flex-shrink: 0; width: 30px; color: var(--text-sub); font-weight: 700; }
.flame-line__opt  { flex: 1; }
.flame-line__pt   { flex-shrink: 0; color: var(--text-sub); font-variant-numeric: tabular-nums; }

/* 1추 줄 — 채도를 낮춘 하늘색 테두리 + 바깥으로 번지는 맥동.
   판 안쪽 여백이 14px이라 번짐(10px)+퍼짐(1px)=11px 로 잡아 잘리지 않게 한다.
   opacity만 움직여 리페인트 없이 GPU 합성만 일어난다. */
.pot-panel.flame-panel .pot-line.is-top {
  position: relative;
  border-color: #9fc4dc;
  color: #dceaf4;
}
.pot-panel.flame-panel .pot-line.is-top .flame-line__rank,
.pot-panel.flame-panel .pot-line.is-top .flame-line__pt { color: #b9d3e4; }
.pot-panel.flame-panel .pot-line.is-top::after {
  content: ""; position: absolute; inset: 0;
  border-radius: inherit; pointer-events: none;
  box-shadow: 0 0 10px 1px rgba(159,196,220,.85);
  opacity: .15;
  animation: flameTopGlow 1.8s ease-in-out infinite;
  will-change: opacity;
}
@keyframes flameTopGlow { 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .pot-panel.flame-panel .pot-line.is-top::after { animation: none; opacity: .5; }
}
/* 화이트 테마에서는 위 색이 전부 밝은 하늘색이라 흰 배경에 묻혀 1추가 안 보였다.
   같은 하늘색 계열을 유지하되 배경까지 옅게 깔고 글자·테두리를 진하게 내린다. */
:root[data-theme="light"] .pot-panel.flame-panel .pot-line.is-top {
  border-color: #2f6f96;
  background: #e8f2f9;
  color: #14384e;
}
:root[data-theme="light"] .pot-panel.flame-panel .pot-line.is-top .flame-line__rank,
:root[data-theme="light"] .pot-panel.flame-panel .pot-line.is-top .flame-line__pt { color: #2f6f96; }
:root[data-theme="light"] .pot-panel.flame-panel .pot-line.is-top::after {
  box-shadow: 0 0 10px 1px rgba(47,111,150,.55);
}

/* ══ 스타포스 강화창 — 게임 UI(GMS v270 UI/Enchant.img/starForce)를 418×720 그대로 옮긴 창 ══
   배경·칸·버튼·숫자는 모두 게임 원본 그림(images/starforce/). 칸 위치는 원본 배치이고
   좁은 화면에서는 starforce_sim.js _sfwFit이 transform으로 통째로 줄인다.
   창 안의 글씨만 우리가 쓴다(원본 칸 그림에 박혀 있는 영어 제목은 그대로 둔다). */
.sf-right#sfRightSimulate { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.sf-right#sfRightSimulate[style*="none"] { display: none; }
.sfw-fit { position: relative; width: 100%; height: 720px; }
.sfw {
  position: absolute; left: 0; top: 0; width: 418px; height: 720px;
  background: url(images/starforce/bg.png) no-repeat; transform-origin: 0 0;
  color: #e6edf3; font-family: Arial, 'Malgun Gothic', sans-serif; font-size: 12px; font-weight: normal; text-shadow: 0 1px 0 rgba(0,0,0,.55);
  user-select: none; -webkit-user-select: none;
}
.sfw > * { position: absolute; box-sizing: border-box; }
.sfw b { font-weight: normal; }
.sfw__rate b { font-weight: 700; }
/* 23성 이상 — 창 테두리가 금색으로 맥동한다. opacity만 움직여 리페인트가 없다 */
.sfw--hi::after {
  content: ""; position: absolute; inset: 0; border-radius: 8px; pointer-events: none;
  box-shadow: inset 0 0 0 2px #ffd429, 0 0 14px 2px rgba(255,196,41,.85);
  opacity: .15; animation: sfstarGlow 1.8s ease-in-out infinite; will-change: opacity;
}
@keyframes sfstarGlow { 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .sfw--hi::after { animation: none; opacity: .8; } }

.sfw__item { left: 152px; top: 59px; width: 114px; height: 114px; display: grid; place-items: center; }
.sfw__item img { width: 44px; height: 40px; image-rendering: pixelated; filter: drop-shadow(0 0 8px rgba(255,212,41,.55)); }
.sfw__item img { visibility: hidden; }
/* 아이템 아이콘은 원본 비율 그대로 가로·세로 2배(요청). 크기를 따로 고정하지 않고 확대만 한다 */
.sfw__item img.is-item { visibility: visible; width: auto; height: auto; transform: scale(2); }
/* 이름 칸은 bg.png에 그려진 이름 바의 어두운 테두리 x 67~351, y 179~208에 딱 맞춘다. 글자가 바 위아래 가운데에 온다 */
.sfw__name { left: 67px; top: 179px; width: 285px; height: 30px; display: grid; place-items: center; font-size: 12px; color: #fff; }

.sfw__sum { left: 66px; top: 240px; width: 286px; height: 37px; background: url(images/starforce/summary.png); display: grid; place-items: center; }
.sfstar-grid { display: flex; flex-wrap: wrap; width: 179px; gap: 6px 0; }
.sfstar-grid__s {
  position: relative; width: 11px; height: 10px; font-size: 0; line-height: 0;
  background: url(images/icons/fav_star_empty.png) no-repeat;
}
.sfstar-grid__s.on { background-image: url(images/icons/fav_star.png); }
/* 5개 묶음 사이를 살짝 띄워 세는 단위를 만든다 */
.sfstar-grid__s:nth-child(5n) { margin-right: 7px; }
.sfstar-grid__s:nth-child(15n) { margin-right: 0; }

.sfw__diff { left: 66px; top: 280px; width: 286px; height: 26px; background: url(images/starforce/diff.png); display: flex; align-items: center; justify-content: center; gap: 22px; }
.sfw__num { display: block; width: 41px; height: 23px; background: url(images/starforce/nums.png) no-repeat; background-position: calc(var(--n, 0) * -41px) 0; }
.sfw__num[data-white="1"] { background-position: calc(var(--n, 0) * -41px) -23px; }
.sfw__arrow { width: 30px; height: 18px; }

.sfw__stat { left: 10px; top: 310px; width: 398px; height: 150px; background: url(images/starforce/stat.png); padding-top: 8px; }
.sfw__row { position: relative; height: 16px; line-height: 16px; font-size: 12px; color: #bed0d3; white-space: nowrap; }
.sfw__row span { position: absolute; right: 221px; }
.sfw__row b { position: absolute; left: 186px; color: #fff; font-variant-numeric: tabular-nums; }
.sfw__row--big b { color: #ffd429; }
.sfw__row b.is-bad { color: #ff8a8a; }
.sfw__done { margin-top: 2px; text-align: center; color: #b8f5c4; font-size: 12px; }

.sfw__prob { left: 10px; top: 463px; width: 398px; height: 70px; background: url(images/starforce/prob.png); padding-top: 11px; }
/* 확률 칸: 이름은 160px, 값은 224px에서 왼쪽 정렬(창 좌표 - 칸 left 10px), 줄 간격 16px */
.sfw__rate { position: relative; height: 16px; line-height: 16px; color: #bed0d3; }
.sfw__rate span { position: absolute; left: 150px; }
.sfw__rate b { position: absolute; left: 214px; font-variant-numeric: tabular-nums; }
.sfw__rate--succ b { color: #8ff2a4; }
.sfw__rate--dest b { color: #ff8a8a; }
.sfw__max { text-align: center; line-height: 46px; color: #ffd429; font-size: 12px; }

.sfw__cost { left: 10px; top: 538px; width: 398px; height: 33px; background: url(images/starforce/cost.png); }
.sfw__cost img { position: absolute; left: 188px; top: 10px; width: 14px; height: 14px; }
.sfw__cost span { position: absolute; left: 206px; top: 0; line-height: 33px; color: #fff; font-size: 12px; font-variant-numeric: tabular-nums; }

/* 버튼 묶음 — 자바스크립트가 보이기/숨기기를 inline으로 바꾸므로 상자 없이 자식만 창 위에 얹는다 */
.sfw__btns { display: contents !important; }
.sfw__sub, .sfw__go { position: absolute; padding: 0; cursor: var(--cur-pointer); }
.sfw__sub {
  top: 634px; width: 129px; height: 30px; border: 1px solid #0a0f14; border-radius: 6px;
  background: linear-gradient(#4a5865, #2c3742); color: #e6edf3; font: inherit; font-size: 12px; font-weight: normal;
}
.sfw__sub:first-child { left: 76px; }
.sfw__sub:nth-child(2) { left: 213px; }
.sfw__sub:hover { filter: brightness(1.15); }
.sfw__sub.sbtn--danger { background: linear-gradient(#a24545, #6b2626); color: #fff; }
.sfw__go {
  left: 147px; top: 675px; width: 129px; height: 35px; border: 0; background: url(images/starforce/btn.png) no-repeat; font-size: 0;
}
/* Safeguard 버튼·Enhancement Mode 슬라이더 — 위치와 크기는 게임 원본. 슬라이더 손잡이만 우리가 그린다 */
.sfw__sg {
  left: 215px; top: 579px; width: 195px; height: 22px; padding: 0; border: 0;
  background: url(images/starforce/sg.png) no-repeat; cursor: var(--cur-pointer); font-size: 0;
}
.sfw__sg:hover:not(:disabled) { background-image: url(images/starforce/sg_hover.png); }
.sfw__sg:active:not(:disabled) { background-image: url(images/starforce/sg_press.png); }
.sfw__sg:disabled { background-image: url(images/starforce/sg_off.png); cursor: default; }
.sfw__sg i { position: absolute; left: 165px; top: 4px; width: 25px; height: 13px; background: url(images/starforce/sg_off_mark.png) no-repeat; }
.sfw__sg.is-on i { left: 166px; top: 5px; width: 23px; height: 11px; background-image: url(images/starforce/sg_on_mark.png); }
.sfw__mode {
  left: 8px; top: 605px; width: 402px; height: 22px; background: url(images/starforce/mode.png) no-repeat;
  cursor: var(--cur-pointer); touch-action: none; outline: none;
}
.sfw__mode.is-off { background-image: url(images/starforce/mode_off.png); cursor: default; }
.sfw__thumb {
  position: absolute; top: 6px; left: calc(188px + (var(--m, 1) - 1) * 62px - 7px); width: 14px; height: 14px;
  border-radius: 50%; border: 1px solid #0a0f14; background: radial-gradient(circle at 35% 30%, #fff, #b9c4cf 70%, #7e8b97);
  box-shadow: 0 1px 2px rgba(0,0,0,.6); transition: left .08s;
}
.sfw__mode.is-off .thumb, .sfw__mode.is-off .sfw__thumb { display: none; }
.sfw__mode:focus-visible { box-shadow: 0 0 0 2px #ffd429; }
.sfw__go:hover { background-image: url(images/starforce/btn_hover.png); }
.sfw__go:active { background-image: url(images/starforce/btn_press.png); }

.sfw-log[hidden] { display: none; }
/* 한 줄로 쌓이는 폭에서는 강화창을 설정 카드 위로 올린다. 직작에서는 창이 주인공이라 맨 위가 맞다 */
@media (max-width: 768px) { .sf-layout > #sfRightSimulate { order: -1; } }

/* ── 23성 이상 성공 시 반짝임 ──
   transform / opacity 만 움직인다. 별이 튀어오르고(pop), 고리가 퍼지고(burst),
   불티가 사방으로 흩어진다(spark). 셋 다 GPU 합성이라 리페인트가 없고,
   0.55초 뒤 끝나는 일회성이라 상시 부하도 없다. */
/* 목표 성수 칸 — 비어 있는 별 위에 금색 별을 겹쳐 opacity만 점멸시켜 어디까지 가야 하는지 보여준다.
   색을 오가게 하면 매 프레임 다시 그려야 하므로 GPU 합성만 일어나는 opacity를 쓴다. */
.sfstar-grid__s.goal::after {
  content: ""; position: absolute; inset: 0; background: url(images/icons/fav_star.png) no-repeat;
  animation: sfStarGoal 2.6s ease-in-out infinite; will-change: opacity;
}
@keyframes sfStarGoal { 0%, 100% { opacity: .06; } 50% { opacity: .95; } }
@media (prefers-reduced-motion: reduce) {
  .sfstar-grid__s.goal::after { animation: none; opacity: .8; }
}

.sfstar-grid__s.pop { animation: sfStarPop .5s ease-out; z-index: 1; }
@keyframes sfStarPop {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.85); }
  100% { transform: scale(1); }
}
/* 퍼지는 고리 */
.sfstar-grid__s.pop::after {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: 24px; height: 24px; margin: -12px 0 0 -12px;
  border-radius: 50%; border: 2px solid rgba(255,212,41,.9);
  pointer-events: none;
  animation: sfStarBurst .55s ease-out forwards;
}
@keyframes sfStarBurst {
  0%   { transform: scale(.25); opacity: 1; }
  100% { transform: scale(1.5);  opacity: 0; }
}
/* 흩어지는 불티 — 점 8개를 box-shadow로 고정해두고 전체를 확대/페이드만 시킨다
   (점마다 요소를 만들면 그만큼 레이어가 늘어난다) */
.sfstar-grid__s.pop::before {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: 3px; height: 3px; margin: -1.5px 0 0 -1.5px;
  border-radius: 50%; pointer-events: none;
  box-shadow:
      0 -11px 0 0 #ffe98a,   8px  -8px 0 0 #ffe98a,
     11px   0   0 0 #ffe98a,  8px   8px 0 0 #ffe98a,
      0  11px 0 0 #ffe98a,  -8px   8px 0 0 #ffe98a,
    -11px   0   0 0 #ffe98a, -8px  -8px 0 0 #ffe98a;
  animation: sfStarSpark .55s ease-out forwards;
}
@keyframes sfStarSpark {
  0%   { transform: scale(.2); opacity: 1; }
  100% { transform: scale(1.5); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .sfstar-grid__s.pop, .sfstar-grid__s.pop::before, .sfstar-grid__s.pop::after { animation: none; }
  .sfstar-grid__s.pop::before, .sfstar-grid__s.pop::after { display: none; }
}

/* ── 설정 카드 헤더 — 제목 좌측, 미라클 타임 토글 우측 ── */
.cube-set-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.cube-dmt { display: flex; align-items: center; gap: 8px; cursor: var(--cur-pointer); font-size: .78rem; font-weight: 700; color: var(--text-sub); user-select: none; }
.cube-dmt input { position: absolute; opacity: 0; width: 0; height: 0; }
.cube-dmt__track { position: relative; width: 36px; height: 20px; border-radius: 999px; background: var(--bg3); border: 1px solid var(--border); transition: .15s; flex-shrink: 0; }
.cube-dmt__thumb { position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 50%; background: var(--text-sub); transition: .15s; }
.cube-dmt input:checked ~ .cube-dmt__track { background: var(--primary); border-color: var(--primary); }
.cube-dmt input:checked ~ .cube-dmt__track .cube-dmt__thumb { left: 18px; background: #fff; }
.cube-dmt:has(input:checked) { color: var(--primary); }

/* ── 잠재옵션 패널 — 테두리·헤더가 등급 색을 따른다 ── */
/* 등급 색 변수(--g-*, --gt-*)는 맨 위 :root에 있다 */
.pot-panel {
  --pot: var(--g-rare);                 /* 기본(레어). data-grade로 덮어쓴다 */
  --pot-t: var(--gt-rare);
  border: 2px solid var(--pot);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--pot) 7%, var(--bg3));
  overflow: hidden;
}
.pot-panel[data-grade="RARE"]      { --pot: var(--g-rare);      --pot-t: var(--gt-rare); }
.pot-panel[data-grade="EPIC"]      { --pot: var(--g-epic);      --pot-t: var(--gt-epic); }
.pot-panel[data-grade="UNIQUE"]    { --pot: var(--g-unique);    --pot-t: var(--gt-unique); }
.pot-panel[data-grade="LEGENDARY"] { --pot: var(--g-legendary); --pot-t: var(--gt-legendary); }

.pot-panel__head {
  display: flex; align-items: center; gap: 7px;
  padding: 10px 14px;
  font-size: .88rem; font-weight: 800; color: var(--pot-t);
  border-bottom: 1px solid color-mix(in srgb, var(--pot) 35%, transparent);
  background: color-mix(in srgb, var(--pot) 10%, transparent);
}
/* 등급 아이콘은 원본이 13px라 확대하면 뭉개진다 — 원본 크기 그대로 쓴다 */
.pot-panel__icon { width: 13px; height: 13px; flex-shrink: 0; image-rendering: pixelated; }
.pot-panel__lines { display: flex; flex-direction: column; gap: 8px; padding: 14px; }
/* 각 줄은 패널 등급이 아니라 "그 줄 옵션이 속한 등급" 색을 쓴다.
   레전드리 패널에 유니크 옵션이 섞여 뜨는(이탈) 걸 눈으로 바로 구분하려는 것. */
.pot-line {
  --line: var(--pot);
  padding: 13px 14px; border-radius: var(--radius-sm);
  /* 흰 글씨 대비는 채도가 아니라 명도가 좌우한다. 어두운 중성색을 섞어
     명도·채도를 함께 낮추되, 테두리는 원색을 유지해 등급 구분은 살린다.
     (레전드리 #ccff00은 원색 그대로면 흰 글씨 대비가 1.2:1로 거의 안 읽힌다) */
  background: color-mix(in srgb, var(--line) 45%, #1a1a22);
  border: 1px solid var(--line);
  font-size: .86rem; font-weight: 700; color: #fff;
  text-shadow: 0 1px 2px rgba(0,0,0,.4);
  text-align: center;
}
.pot-line[data-grade="RARE"]      { --line: var(--g-rare); }
.pot-line[data-grade="EPIC"]      { --line: var(--g-epic); }
.pot-line[data-grade="UNIQUE"]    { --line: var(--g-unique); }
.pot-line[data-grade="LEGENDARY"] { --line: var(--g-legendary); }
.pot-line--empty { background: var(--bg2); border-color: var(--border); color: var(--text-sub); font-weight: 500; }
/* 결과 줄 — 모든 시뮬레이터가 같이 쓴다 */
.sf-res-item { display: flex; justify-content: space-between; align-items: center; padding: 8px 0; border-bottom: 1px solid var(--border); }
.sf-res-item:last-child { border-bottom: none; }
.sf-res-label { font-size: .86rem; color: var(--text-sub); }
.sf-res-val { font-size: .98rem; font-weight: 800; color: var(--text); }
.sf-res-val.big { font-size: 1.2rem; color: var(--accent); text-shadow: 0 0 8px rgba(var(--star),.35); }

/* ── 시뮬레이터 공통 탭·토글 ── */
.sec-sep { border: none; border-top: 1.5px solid var(--border); margin: 0 0 20px; }
.sf-tabs { display: flex; gap: 0; margin-bottom: 12px; border-radius: 12px; overflow: hidden; border: 1.5px solid var(--border); width: fit-content; }
/* transition:all 이면 테마를 바꿀 때 var(--primary) 변화가 제대로 반영되지 않아
   이미 그려진 탭이 이전 테마 색(보라)을 그대로 붙들고 있었다. 실제로 화이트
   테마인데 활성 탭만 다크용 보라로 남아 "선택 안 된 것처럼" 보였다.
   색은 테마를 따라 즉시 바뀌어야 하므로 transition 대상에서 뺀다. */
.sf-tab { padding: 10px 28px; font-size: .9rem; font-weight: 700; background: transparent; color: var(--text-sub); border: none; border-right: 1px solid var(--border); cursor: var(--cur-pointer); }
.sf-tab:last-child { border-right: none; }
.sf-tab.active { background: var(--primary); color: #fff; }
.sf-tab:hover:not(.active) { background: rgba(var(--hue),.1); color: var(--text); }
/* flex-wrap 안전망 — 그리드 수정 후에도 극단적으로 좁은 폭에서는 줄바꿈으로 대응 */
.sf-toggle-group { display: flex; gap: 0; flex-wrap: wrap; border-radius: 10px; overflow: hidden; border: 1.5px solid var(--border); }
.sf-toggle { flex: 1; padding: 10px 10px 8px; font-size: .83rem; background: transparent; color: var(--text-sub); border: none; border-right: 1px solid var(--border); cursor: var(--cur-pointer); transition: all .15s; display: flex; flex-direction: column; align-items: center; gap: 2px; }
.sf-toggle:last-child { border-right: none; }
.sf-toggle.active { background: var(--primary); color: #fff; font-weight: 700; }
.sf-toggle:hover:not(.active) { background: rgba(var(--hue),.1); color: var(--text); }

/* ── 스타포스 스테이지 버튼 ── */
.sf-stage-row2 { display: flex; align-items: center; gap: 6px; padding: 3px 0; border-bottom: 1px solid rgba(255,255,255,.04); }
.sf-stage-lbl2 { font-size: .8rem; color: var(--text-sub); min-width: 50px; font-weight: 700; flex-shrink: 0; }
select.sel.sf-stage-sel { width: 80px; flex-shrink: 0; font-size: .8rem; padding: 2px 4px; }
.sf-stage-info { display: flex; gap: 6px; font-size: .72rem; flex: 1; }
.sf-stage-prob--succ { color: var(--success); }
.sf-stage-prob--fail { color: var(--text-dim); }
.sf-stage-prob--dest { color: var(--danger); }

/* ── 스타포스 결과 ── */
.sf-log { margin-top: 12px; display: flex; flex-direction: column; gap: 4px; max-height: 320px; overflow-y: auto; }
.sf-log-row { display: flex; align-items: center; gap: 8px; padding: 5px 8px; border-radius: 7px; font-size: .82rem; }
.log-success { background: rgba(34,197,94,.1); }
.log-fail    { background: rgba(255,255,255,.04); }
.log-destroy { background: rgba(239,68,68,.12); }
.sf-log-icon { font-size: .9rem; width: 18px; text-align: center; }
.sf-log-desc { flex: 1; color: var(--text); }
.sf-log-cost { color: var(--text-sub); font-size: .78rem; }

/* ── 큐브 목표 옵션 ── */
.cube-type-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 6px; }
.cube-type-btn { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; padding: 10px 8px; border-radius: var(--radius-sm); background: var(--bg3); border: 1.5px solid var(--border); color: var(--text-sub); font-size: .82rem; font-weight: 700; cursor: var(--cur-pointer); transition: .15s; opacity: .6; }
/* 원본 픽셀 크기 그대로, 100px 상자보다 큰 것만 줄인다(사이드바 아이콘과 동일한 원칙) */
.cube-type-btn img { width: auto; height: auto; max-width: 100px; max-height: 100px; object-fit: contain; }
.cube-type-btn:not([disabled]):hover { border-color: var(--primary); opacity: 1; }
.cube-type-btn:hover:not(.active) { color: var(--text); }
.cube-type-btn.active { border-color: var(--primary); background: var(--primary-l); color: var(--primary); opacity: 1; box-shadow: 0 0 12px rgba(var(--hue),.25); }
.cube-type-btn[disabled] { cursor: not-allowed; }



.cube-btns { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; }
.cube-btn-full { width: 100%; text-align: center; }

/* ── 까미 월루 목표 프리셋 버튼 ── */
.hr-preset { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0; }
.hr-preset__btn { padding: 6px 12px; font-size: .78rem; }

/* 큐브 결과 모달 */
.modal--cube-result { width: min(1000px, 96vw); max-height: 90vh; display: flex; flex-direction: column; }
.modal--cube-result .modal__body { flex: 1; overflow: hidden; display: flex; flex-direction: column; padding: 16px 20px 20px; }
.cube-result-body { display: flex; gap: 24px; flex: 1; overflow: hidden; padding: 16px 20px 20px; }
.cube-result-left { flex: 0 0 300px; display: flex; flex-direction: column; gap: 4px; }
.cube-result-left .sf-res-item { padding: 10px 0; }
.cube-result-right { flex: 1; overflow-y: auto; border: 1px solid var(--border); border-radius: 10px; padding: 14px 16px; }
.cube-combo-note { font-size: .8rem; color: var(--text-sub); margin-bottom: 10px; }
.cube-combo-item { padding: 10px 0; border-bottom: 1px solid var(--border); }
.cube-combo-item:last-child { border-bottom: none; }
.cube-combo-line { display: block; font-size: .88rem; color: var(--text); line-height: 1.6; }
.cube-combo-p { display: block; font-size: .8rem; color: var(--accent); margin-top: 4px; font-weight: 600; }
.mb8 { margin-bottom: 8px; }

/* 큐브 옵션 세트 */
.cube-set, .hr-set { border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px; margin-bottom: 10px; }
.hr-set { cursor: var(--cur-pointer); }
.hr-set--active { border-color: var(--primary); box-shadow: 0 0 0 1px var(--primary); }
.cube-set__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.cube-set__title { font-size: .85rem; font-weight: 600; color: var(--text-sub); }
.cube-set__del { background: none; border: none; color: var(--text-sub); cursor: var(--cur-pointer); font-size: .9rem; padding: 2px 6px; border-radius: 4px; line-height: 1; }
.cube-set__del:hover { color: var(--danger); background: var(--bg-hover); }
.cube-goal-hint { color: var(--text-sub); font-size: .8rem; line-height: 1.5; margin: 4px 0 8px; }
.cube-goal-row { display: flex; align-items: center; gap: 6px; margin-bottom: 6px; }
.cube-goal-row .sel { flex: 1; min-width: 0; }
.cube-goal-row .cube-opt-inp { width: 72px; flex: 0 0 72px; text-align: right; }
.cube-goal-row .cube-opt-unit { color: var(--text-sub); font-size: .85rem; white-space: nowrap; min-width: 14px; }

/* ── 보스 트래커 난이도 버튼 ── */
.boss-diff-wrap { display: flex; align-items: center; gap: 8px; }
/* 진짜 원인: 기본 폰트 '고딕'이 실제로는 ONE_Mobile_Title.ttf(장식용 타이틀 폰트)에
   매핑되어 있어 일반 UI 폰트보다 글자 폭이 훨씬 넓다. body에 인라인으로 걸리는
   폰트(app.js applyFont)를 그대로 물려받으면 사용자가 고른 폰트에 따라 pill 안
   "EXTREME"이 박스를 넘기는 정도가 달라짐 → 이 작은 배지만은 폰트 선택과
   무관하게 항상 시스템 UI 폰트를 쓰도록 고정하고, 박스도 80px로 더 키움 */
.boss-diff-pill { width: 80px; flex-shrink: 0; display: flex; justify-content: center; }
.boss-diff-pill .dpill { pointer-events: none; padding: 3px 4px; width: 100%; justify-content: center; overflow: hidden; }
.boss-diff-pill .dpill .dpill__t {
  font-family: 'Segoe UI', 'Malgun Gothic', sans-serif;
  font-size: .62rem;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.boss-diff-sel {
  appearance: none; -webkit-appearance: none;
  background: var(--bg3) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23888'/%3E%3C/svg%3E") no-repeat right 8px center;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  color: var(--text); font-size: .78rem; padding: 5px 28px 5px 10px;
  width: 110px;
  cursor: var(--cur-pointer); transition: border-color .15s;
}
.boss-diff-sel:hover { border-color: var(--border-hl); }
.boss-diff-sel:focus { outline: none; border-color: var(--primary); }
.boss-diff-sel option { background: var(--bg2); color: var(--text); }

/* ── BOSS HP 카드 ── */
/* 5열 고정이었더니 창을 좁히면 칸이 강제로 짓눌려 이름이 "유\n피\n테\n르"처럼
   한 글자씩 세로로 쪼개졌다(모바일 캘린더에서 겪었던 것과 같은 유형의 버그).
   auto-fill로 바꿔 칸이 최소 폭 밑으로는 안 줄고, 대신 알아서 다음 줄로 내려가게 한다. */
/* 8열을 상한으로 두고, 그보다 넓어지면 카드가 계속 커지는 게 아니라 오른쪽에
   여백만 남긴다. auto-fill+minmax만 쓰면 화면이 넓을수록 9열, 10열로 끝없이
   늘어나므로(실제로 그랬음) 그리드가 커질 수 있는 폭 자체를 막아둔다.
   상한 폭 = 8칸 × 190px + 칸사이 7개 × 12px = 1604px.
   좁아지면 auto-fill이 알아서 7,6,…,2,1열로 줄인다
   (캐릭터 카드 .cg-grid에서 이미 쓰던 것과 같은 패턴). */
.bhp-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(max(190px, calc((100% - 48px) / 5)), 1fr));
  grid-auto-rows: 1fr; gap: 12px; max-width: none;
}
.bhp-card {
  background: var(--panel-veil);
  border: 1px solid rgba(var(--hue),.22);
  border-radius: var(--radius-lg); overflow: hidden;
  box-shadow: var(--shadow); display: flex; flex-direction: column;
  transition: border-color .22s, transform .22s cubic-bezier(.2,.8,.2,1); color: var(--text);
}
.bhp-card:hover { border-color: var(--border-hl); transform: translateY(-3px); }
.bhp-card--monthly { border: 2px solid rgba(216,177,90,.8); }
.bhp-card__img {
  width: 100%; aspect-ratio: 1/1;
  background: linear-gradient(160deg,#1e3545 0%,#0c1a28 100%);
  display: flex; align-items: center; justify-content: center;
  overflow: hidden; flex-shrink: 0;
}
.bhp-card__img img { width: 100%; height: 100%; object-fit: cover; }
.bhp-card__img--clickable { cursor: var(--cur-pointer); position: relative; }
.bhp-card__img--clickable:hover img { filter: brightness(1.1); }
.modal.modal--boss-drop { width: min(1180px, 96vw); }
.modal--boss-drop .modal__body { max-height: 84vh; overflow-y: auto; }
/* 헤더엔 보스 이름만 크게.
   .modal__title이 이 줄보다 파일 뒤쪽(1249줄)에 있어 명세도가 같으면 그쪽이 이긴다
   → 클래스 두 개로 명세도를 올려야 실제로 먹는다(HANDOFF "버그 패턴 2"와 동일 계열). */
.modal__title.modal__title--boss { font-size: 1.6rem; font-weight: 900; letter-spacing: -.3px; }
.bhp-drop-modal { display: flex; gap: 24px; align-items: flex-start; }
.bhp-drop-modal__img {
  /* 세로가 너무 커지면 모달이 스크롤돼서 아이템을 보려고 내려야 한다 → 화면 높이에도 맞춤 */
  flex: 0 0 clamp(280px, min(44vw, 68vh), 620px);
  width: clamp(280px, min(44vw, 68vh), 620px); height: clamp(280px, min(44vw, 68vh), 620px);
  border-radius: 10px;
  /* 흰 배경 고정(테마 무관) — 어두운 배경에선 보스 외곽이 뭉개져 보였음 */
  background: #fff;
  border: 1px solid var(--border);
  display: flex; align-items: center; justify-content: center; overflow: hidden;
  padding: 10px; box-sizing: border-box;
}
/* cover는 원본 비율과 안 맞으면 보스를 잘라먹는다 → contain으로 전체가 보이게 */
.bhp-drop-modal__img img { width: 100%; height: 100%; object-fit: contain; }
.bhp-drop-modal__items { flex: 1; min-width: 0; }
.bhp-drop-modal__itemshead {
  font-size: 1.32rem; font-weight: 900; color: var(--text);
  padding-bottom: 11px; margin-bottom: 14px; border-bottom: 1px solid var(--border);
}
/* 난이도별 구획 — 이지/노말/하드…를 한 화면에 전부 나열 */
.bhp-drop-sec { margin-bottom: 16px; }
.bhp-drop-sec:last-child { margin-bottom: 0; }
/* 난이도 표기는 앱 공용 .dpill 재사용 (EASY/NORMAL/HARD…) */
.bhp-drop-sec__diff { margin-bottom: 10px; }
/* 글자 길이가 달라도(EASY vs EXTREME) 박스 크기는 같게 — 폭 고정 */
.bhp-drop-sec__diff .dpill {
  cursor: var(--cur-default); pointer-events: none;
  width: 108px; padding-left: 4px; padding-right: 4px; overflow: hidden;
}
/* 기본 폰트 '고딕'(ONE_Mobile_Title)은 폭이 넓어 EXTREME 같은 긴 글자가 잘린다
   — 보스 테이블 필과 동일하게 UI 폰트로 고정 */
.bhp-drop-sec__diff .dpill__t { font-family: 'Segoe UI', 'Malgun Gothic', sans-serif; }
.bhp-drop-modal__empty { margin: 0; font-size: .88rem; line-height: 1.6; color: var(--text-sub); }
/* 아이콘을 옆으로 나열하다 넘치면 다음 줄로 — 세로로 길어져 스크롤 생기던 것 해소 */
.bhp-drop-modal__itemlist { display: flex; flex-wrap: wrap; gap: 9px; }
.bhp-drop-item { position: relative; display: block; line-height: 0; cursor: var(--cur-pointer); }
.bhp-drop-item__icon {
  width: 58px; height: 58px; object-fit: contain; padding: 6px;
  background: rgba(var(--hue),.08); border: 1px solid var(--border); border-radius: 8px;
  transition: border-color .13s, transform .13s;
}
.bhp-drop-item:hover .bhp-drop-item__icon,
.bhp-drop-item:focus-visible .bhp-drop-item__icon {
  border-color: var(--primary); transform: translateY(-2px);
}
/* 이름은 평소엔 숨기고 마우스를 올릴 때만 툴팁으로 */
.bhp-drop-item__name {
  position: absolute; left: 50%; bottom: calc(100% + 9px); transform: translateX(-50%);
  z-index: 5; padding: 7px 13px; border-radius: 8px;
  background: var(--bg-card); border: 2px solid var(--border-hl, var(--primary));
  box-shadow: 0 5px 18px rgba(0,0,0,.5);
  font-size: 1rem; font-weight: 800; line-height: 1.25; color: var(--text);
  white-space: nowrap; pointer-events: none;
  opacity: 0; visibility: hidden; transition: opacity .13s;
}
.bhp-drop-item:hover .bhp-drop-item__name,
.bhp-drop-item:focus-visible .bhp-drop-item__name { opacity: 1; visibility: visible; }

/* 아이템을 클릭하면 뜨는 인게임 설명 — body 직속 고정 위치(모달 스크롤에 안 잘리게) */
.bhp-item-desc {
  position: fixed; left: 0; top: 0; z-index: 2000;
  width: max-content; max-width: 240px;
  padding: 10px 14px; border-radius: 10px;
  background: var(--bg-card, var(--bg2)); border: 2px solid var(--border-hl, var(--primary));
  box-shadow: 0 8px 24px rgba(0,0,0,.5);
  pointer-events: none;
  opacity: 0; visibility: hidden; transition: opacity .13s;
}
.bhp-item-desc.open { opacity: 1; visibility: visible; }
.bhp-item-desc__name { font-size: .92rem; font-weight: 900; color: var(--text); margin-bottom: 4px; }
.bhp-item-desc__body { font-size: .82rem; line-height: 1.5; color: var(--text-sub); white-space: normal; }
@media (max-width: 640px) {
  .bhp-drop-modal { flex-direction: column; align-items: center; }
  .bhp-drop-modal__items { width: 100%; }
}
.bhp-card__body { padding: 12px 14px; display: flex; flex-direction: column; flex: 1; }
.bhp-card__top { display: flex; flex-direction: column; gap: 7px; }
.bhp-card__name { font-size: 1.05rem; font-weight: 900; display: flex; align-items: center; gap: 6px; color: var(--text); flex: 1; min-width: 0; overflow: hidden; }
.bhp-card__name-t { display: inline-block; white-space: nowrap; transform-origin: left center; }
.bhp-card__info { display: flex; align-items: center; justify-content: space-between; gap: 6px; }
.bhp-lv { font-size: .82rem; color: var(--text-sub); font-weight: 800; }
/* 선택된 난이도 pill (Lv/포스 아래, select 위) */
.bhp-active-diff { display: flex; }
.bhp-active-diff .dpill {
  flex: 1; width: 100%;
  font-size: 1.3rem; font-weight: 900; padding: 4px 0;
  filter: none; justify-content: center;
  font-family: 'Segoe UI', 'Malgun Gothic', sans-serif;
  letter-spacing: .5px;
}
/* 난이도 select */
.bhp-diff-sel {
  width: 100%;
  background-color: rgba(255,255,255,.07);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 7px 30px 7px 14px;
  color: var(--text);
  font-family: 'Segoe UI', 'Malgun Gothic', sans-serif;
  font-size: .78rem; font-weight: 700;
  cursor: var(--cur-pointer); outline: none;
  transition: border-color .15s, background-color .15s;
  appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='5' viewBox='0 0 9 5'%3E%3Cpath d='M0 0l4.5 5L9 0z' fill='%23ffffff88'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 11px center;
}
.bhp-diff-sel:hover { border-color: var(--border-hl); background-color: rgba(255,255,255,.11); }
.bhp-diff-sel:focus { border-color: var(--primary); background-color: rgba(255,255,255,.13); }
.bhp-diff-sel option { background: var(--bg2); color: var(--text); }
/* HP 내용 */
.bhp-diff { border-top: 1px solid var(--border); padding-top: 8px; margin-top: 2px; }
.bhp-phase { display: flex; justify-content: space-between; gap: 8px; font-size: .88rem; padding: 3px 0; color: var(--text-sub); }
.bhp-phase__val { font-weight: 900; color: var(--text); text-align: right; }
.bhp-sep { border: none; border-top: 1px dashed var(--border); margin: 4px 0; }
.bhp-pdr { font-size: .8rem; color: var(--text-sub); margin-bottom: 4px; }
.bhp-pdr b { color: var(--text); }
.bhp-thresholds { display: flex; flex-direction: column; align-items: flex-end; margin-top: auto; padding-top: 8px; gap: 2px; }
.bhp-tr { display: flex; align-items: center; gap: 5px; font-size: .82rem; font-weight: 800; }
.bhp-tr__pct { color: var(--text-sub); font-size: .72rem; font-weight: 700; }
.bhp-tr__dot--10 { color: var(--success); font-size: .65rem; }
.bhp-tr__dot--5  { color: #60a5fa; font-size: .65rem; }
.bhp-tr__val { color: var(--text); }
.force { display: inline-flex; align-items: center; gap: 4px; min-width: 40px; text-align: center; padding: 2px 9px; border-radius: 99px; font-size: .7rem; font-weight: 800; }
.force-icon { width: 18px; height: 18px; object-fit: contain; flex-shrink: 0; }
.force-arc { background: rgba(96,165,250,.15); color: #60a5fa; }
.force-auth { background: rgba(163,128,225,.16); color: #a380e1; }

/* ── 앱 설치 안내 배너 ──
   ★ 화면 위에 "띄우는"(position:fixed) 방식은 그만뒀다. 띄우면 그 밑 내용과
     겹치지 않게 하려고 top 값을 직접 계산해야 하는데, 그 계산이 배너 높이가
     바뀔 때마다(스누즈 버튼 줄바꿈, 배너 2개 겹침 등) 틀어져서 캐릭터 카드
     목록과 계속 겹쳤다(실제로 반복 제보됨).
     대신 .content 맨 위에 있는 "평범한 블록"으로 둔다. 배너가 있으면 그만큼
     자동으로 아래 내용이 밀리고, 없으면(display:none) 자리도 없다. 계산 없이
     항상 맞는다. */
/* ★ "일주일간 보지 않기"를 예전엔 position:absolute로 우상단에 얹었다. absolute는
   layout에서 자기 자리를 차지하지 않으므로, 확인/닫기 줄이 좁아져 두 줄로 접히면
   그 위에 그냥 겹쳐 보였다(실제로 겹침 반복 제보). 겹칠 자리 자체를 없애려면
   스누즈를 진짜 한 줄로 넣어야 한다 — 그래서 배너를 세로로 쌓아(column) 스누즈를
   위쪽 독립된 줄로 두고, 아이콘·문구·버튼은 그 아래 별도 줄(.pwa-install__row)에
   둔다. 배너가 필요한 만큼 위아래로 늘어나며 절대 겹치지 않는다. */
/* fixed로 카드 목록 위에 덮어씌우는 느낌을 원해서 되돌렸다. 예전에 겹침으로
   문제였던 건 이 "덮어씌움" 자체가 아니라 배너 안쪽 글자(스누즈/확인/닫기)끼리
   겹치던 것이었고, 그건 위의 __row/__info/__actions 구조로 이미 해결됐다.
   사이드바까지 포함한 전체 폭이라, 헤더와 같은 좌우 여백(24px, 좁은 화면은
   14px)을 줘서 카드 목록 좌우 끝과 줄을 맞춘다. */
.top-banners {
  position: fixed; top: var(--top-h); left: 0; right: 0; z-index: 50;
  display: flex; flex-direction: column;
  padding: 10px 24px 0;
}
@media (max-width: 520px) { .top-banners { padding: 8px 14px 0; } }
/* 위에서 스르륵 떨어지는 느낌 — 배너가 새로 뜰 때마다 재생되게 애니메이션은
   .open이 막 붙는 순간에만 건다(JS에서 opening 클래스를 잠깐 얹었다 뗀다). */
@keyframes pwaInstallDrop {
  from { transform: translateY(-12px); opacity: 0; }
  to   { transform: translateY(0);     opacity: 1; }
}
.pwa-install {
  display: none;
  flex-direction: column;
  margin: 0 0 14px;
  padding: 14px;
  background: var(--bg2); border: 1px solid var(--border-hl);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
  gap: 6px;
}
.pwa-install.open { display: flex; }
.pwa-install.opening { animation: pwaInstallDrop .28s ease-out; }
/* 문구 줄(.pwa-install__info)과 버튼 줄(.pwa-install__actions)을 아예 분리한다.
   한 줄에 같이 두면 버튼 높이에 맞춰 문구가 눌리는데, 따로 두면 문구가
   자기 줄 안에서 독립적으로 세로 중앙(그냥 한 줄이라 자연히 중앙)에 온다. */
.pwa-install__row { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.pwa-install__info { display: flex; align-items: center; gap: 12px; min-width: 0; flex: 1; }
.pwa-install__actions { display: flex; align-items: center; gap: 8px; flex: none; }
.pwa-install__icon { width: 44px; height: 44px; border-radius: 10px; flex: none; }
.pwa-install__txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.pwa-install__txt b { font-size: .9rem; font-weight: 900; color: var(--text); }
.pwa-install__txt span { font-size: .76rem; color: var(--text-sub); line-height: 1.35; }
.pwa-install .sbtn { flex: none; }
.pwa-install__close { color: var(--text-dim); }
/* 배너 안에서는 주 버튼도 그림자를 빼서 닫기 버튼과 같은 평면으로 맞춘다.
   좁은 배너 안에서 혼자 떠 보이면 어색하다. */
.pwa-install .sbtn--primary { box-shadow: none; }
.pwa-install .sbtn--primary:hover { box-shadow: none; transform: none; }
/* 문장 안에 들어가는 공유 버튼 모양. 글자 크기·색을 그대로 따라가게 둔다 */
.pwa-glyph {
  width: 1em; height: 1em; vertical-align: -0.15em;
  margin: 0 1px; color: var(--text);
}
/* 좁은 화면에서는 버튼을 아래 줄로 내리고, 아이콘과 글씨는 같은 줄에 둔다.
   ★ 글씨 영역에 min-width가 꼭 있어야 한다. flex-basis가 0이면 "폭 0까지 줄이면
     한 줄에 다 들어간다"고 계산해서 줄바꿈이 일어나지 않고, 대신 글씨 영역이
     40px대로 짓눌려 글자가 세로로 쪼개진다(실제로 그렇게 깨졌었다). */
@media (max-width: 520px) {
  /* 스누즈는 이제 자기 줄이 따로 있어 겹칠 일이 없다. 좁을 때는 문구 줄
     (.pwa-install__info) 아래로 버튼 줄(.pwa-install__actions)을 내린다. */
  .pwa-install__row { flex-wrap: wrap; }
  .pwa-install__info { flex: 1 1 100%; min-width: 0; }
  .pwa-install__txt { min-width: 150px; }
  /* ★ 여기 white-space:nowrap이 버튼 세 개("일주일간 보지 않기"/확인·설치/닫기)를
     한 줄에 다 욱여넣으려 해서, 좁은 폰에서 폭을 넘긴 만큼 배너가 옆으로
     삐져나갔다(실제로 그렇게 깨졌었다). 버튼 자체 글자는 각자 sbtn에서 이미
     한 줄로 유지되니, 부모는 줄바꿈을 허용해 버튼째로 다음 줄로 내려가게 한다. */
  .pwa-install__actions { flex: 1 1 100%; justify-content: flex-end; flex-wrap: wrap; row-gap: 6px; }
}
/* 홈 화면 앱으로 실행 중이면 설치 안내는 의미가 없다 */
@media (display-mode: standalone) { .pwa-install { display: none !important; } }

/* ── MODAL ── */
.overlay {
  display: none; position: fixed; inset: 0;
  background: var(--panel-veil);
  
  z-index: 1000; align-items: center; justify-content: center;
}
.overlay.open { display: flex; }
.modal {
  background: var(--bg2);
  border: 1px solid var(--border-hl);
  border-radius: var(--radius-lg);
  width: min(520px,95vw);
  box-shadow: var(--shadow-lg);
  display: flex; flex-direction: column; overflow: hidden;
  animation: modalIn .22s cubic-bezier(.2,.8,.2,1);
}
@keyframes modalIn { from { opacity:0; transform:translateY(14px) scale(.97) } to { opacity:1; transform:none } }
.modal--sm { width: min(360px,95vw); }
.modal__head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 22px; border-bottom: 1px solid var(--border);
  background: var(--bg3);
}
.modal__title { font-size: .98rem; font-weight: 800; color: var(--text); }
.modal__close {
  width: 28px; height: 28px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: var(--text-sub); transition: .15s;
}
.modal__close:hover { background: var(--danger-l); color: var(--danger); }
.modal__body {
  padding: 20px 22px; display: flex; flex-direction: column; gap: 14px;
  max-height: 70vh; overflow-y: auto;
}
.modal__foot {
  padding: 14px 22px; border-top: 1px solid var(--border);
  display: flex; justify-content: flex-end; gap: 10px;
  background: var(--bg3);
  /* 버튼 글자가 길면(예: "다음 업데이트까지 보지 않기") 좁은 화면에서 한 글자씩
     세로로 쪼개진다. 줄바꿈을 허용해 버튼째로 아랫줄로 내려가게 한다. */
  flex-wrap: wrap;
}
.modal__foot .sbtn { white-space: nowrap; }
/* ── 메이플 캘린더 ── */
.mc-panel {
  background: var(--bg2); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: 16px 18px;
  display: flex; flex-direction: column; gap: 12px;
}
.mc-sec__label { font-size: 1.06rem; font-weight: 900; color: var(--text); }
.mc-sec__sub { font-size: .84rem; font-weight: 700; color: var(--text-dim); margin-left: 8px; }

/* 지금 보고 있는 캐릭터 — 누르면 선택 모달이 열린다 */
.mc-topbar {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 12px;
}
.mc-charchip {
  display: flex; align-items: center; gap: 12px;
  padding: 8px 16px 8px 10px;
  background: var(--bg3); border: 2px solid var(--border);
  border-radius: var(--radius-lg); transition: .15s;
}
.mc-charchip:hover { border-color: var(--primary); background: rgba(var(--hue),.12); }
/* 넥슨 아바타 원본은 96px인데 62px 칸에 눌러 담아 실제보다 작아 보였다.
   사이드바 캐릭터 카드·프론티어 덱과 같은 정도(112px)로 맞춘다. */
.mc-charchip__face {
  width: 112px; height: 112px; flex-shrink: 0;
  display: flex; align-items: flex-end; justify-content: center; overflow: hidden;
}
.mc-charchip__face img { max-width: 100%; max-height: 100%; object-fit: contain; image-rendering: pixelated; }
.mc-charchip__body { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; }
.mc-charchip__name { font-size: 1.1rem; font-weight: 900; color: var(--text); }
.mc-charchip__lv { font-size: .82rem; font-weight: 700; color: var(--text-dim); }
.mc-charchip__sub { font-size: .8rem; font-weight: 700; color: var(--text-dim); }
.mc-allbtn { margin-left: auto; }   /* 전체 보기는 오른쪽 끝에 */
.sbtn.is-off { opacity: .4; cursor: var(--cur-default); }
/* 전체 보기 중에는 "기록할 캐릭터"가 잠시 물러난다는 걸 눈으로 알려준다 */
.mc-charchip.dim { opacity: .55; }

/* 전체 보기의 날짜 모달 — 캐릭터별 묶음 */
.mc-allblock {
  display: flex; flex-direction: column; gap: 6px;
  padding-bottom: 14px; border-bottom: 1px solid var(--border);
}
.mc-allblock:last-of-type { padding-bottom: 0; border-bottom: none; }
.mc-allblock__head {
  display: flex; align-items: center; gap: 8px;
  font-size: 1.02rem; font-weight: 900; color: var(--text);
}
.mc-allblock__head img { width: 34px; height: 34px; object-fit: contain; }
.mc-allblock__items { display: flex; flex-wrap: wrap; gap: 6px; }
.mc-allblock__item {
  width: 40px; height: 40px; object-fit: contain; padding: 4px;
  background: var(--bg3); border: 1px solid var(--border); border-radius: var(--radius-sm);
}

/* 캐릭터 고르기 */
.mc-chars { display: flex; flex-wrap: wrap; gap: 12px; }
.mc-char {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  width: 140px; padding: 14px 8px;
  background: var(--bg3); border: 2px solid transparent;
  border-radius: var(--radius-sm); transition: .15s;
}
.mc-char:hover { border-color: var(--border-hl); }
.mc-char.sel { border-color: var(--primary); background: rgba(var(--hue),.14); }
.mc-char__face {
  width: 112px; height: 112px; overflow: hidden;
  display: flex; align-items: flex-end; justify-content: center;
}
/* 넥슨 아바타 원본은 96×96인데 이 칸(110px)은 그보다 살짝 키워서 쓴다 —
   사이드바 캐릭터 카드·프론티어 덱과 같은 정도(1.1배 안팎)로, 픽셀아트라 보간을 끈다. */
.mc-char__face img { max-width: 100%; max-height: 100%; object-fit: contain; image-rendering: pixelated; }
.mc-char__name {
  font-size: .92rem; font-weight: 800; color: var(--text-sub);
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mc-char__lv { font-size: .74rem; font-weight: 700; color: var(--text-dim); }

/* 날짜 모달 — 일정과 아이템을 여기서 기록한다 */
.modal.modal--mc-day { width: min(880px, 95vw); }
.modal--mc-day .modal__body { max-height: 78vh; gap: 22px; }
.modal__title.modal__title--mc { font-size: 1.3rem; font-weight: 900; letter-spacing: -.3px; }

/* 일정 / 아이템 탭 */
.mc-tabs {
  display: flex; gap: 4px; padding: 0 22px;
  background: var(--bg3); border-bottom: 1px solid var(--border);
}
.mc-tab {
  padding: 12px 20px; margin-bottom: -1px;
  border-bottom: 3px solid transparent;
  font-size: 1rem; font-weight: 800; color: var(--text-dim);
  transition: .15s;
}
.mc-tab:hover { color: var(--text-sub); }
.mc-tab.sel { color: var(--primary); border-bottom-color: var(--primary); }
/* 안 보이는 탭은 완전히 빼서 모달 높이에 영향을 주지 않게 한다 */
.mc-pane { display: none; flex-direction: column; gap: 12px; }
.mc-pane.on { display: flex; }
.mc-sec__label--sub {
  margin-top: 6px; padding-top: 14px;
  border-top: 1px solid var(--border);
  font-size: .98rem;
}

/* 달력 */
/* 좁은 화면에서 4개가 한 줄에 안 들어가면 "이번 달로 이동"이 세로로 짓눌리므로 줄바꿈을 허용한다 */
.mc-cal__head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; justify-content: center; }
.mc-cal__title { font-size: 1.16rem; font-weight: 900; min-width: 8.5em; text-align: center; }
#mcToday { white-space: nowrap; margin-left: auto; }
@media (max-width: 768px) {
  #mcToday { margin-left: 0; }
}
.mc-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 5px; }
.mc-dow {
  text-align: center; padding: 5px 0;
  font-size: .84rem; font-weight: 800; color: var(--text-dim);
}
.mc-dow.sun, .mc-cell.sun .mc-cell__d { color: var(--danger); }
.mc-dow.sat, .mc-cell.sat .mc-cell__d { color: #6ea8ff; }
.mc-cell {
  aspect-ratio: 1 / 1; padding: 5px; overflow: hidden;
  display: flex; flex-direction: column; align-items: stretch; gap: 3px;
  background: var(--bg3); border: 2px solid transparent;
  border-radius: var(--radius-sm); text-align: left; transition: .12s;
}
.mc-cell--pad { background: transparent; }
.mc-cell:hover { border-color: var(--border-hl); }
.mc-cell.today { background: rgba(var(--hue),.10); }
.mc-cell.sel { border-color: var(--primary); }
.mc-cell__d { font-size: .84rem; font-weight: 800; color: var(--text-sub); flex-shrink: 0; }
/* 일정 라벨은 날짜 바로 밑에서부터 위→아래로 채운다 */
.mc-cell__evs { display: flex; flex-direction: column; gap: 2px; min-height: 0; overflow: hidden; }
.mc-cell__ev {
  display: block; padding: 1px 5px; border-radius: 4px;
  font-size: .68rem; font-weight: 800; line-height: 1.5;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* margin-top:auto → 아이템은 라벨이 몇 개든 항상 칸 맨 아래에 붙는다.
   nowrap이 핵심 — flex-shrink:0이라 줄바꿈되는 순간 그만큼 칸 높이를 뚫고 나가
   overflow:hidden에 통째로 잘려 아이템이 아예 안 보였다. 개수는 mcalendar.js가
   칸 폭을 재서 한 줄에 들어갈 만큼만 그리고, 나머지는 +N으로 접는다. */
.mc-cell__icons {
  display: flex; flex-wrap: nowrap; gap: 2px; align-items: center;
  margin-top: auto; flex-shrink: 0; overflow: hidden;
}
.mc-cell__icons img { width: 21px; height: 21px; object-fit: contain; flex-shrink: 0; }
.mc-cell__more { font-size: .7rem; font-weight: 800; color: var(--text-dim); }

/* ── 칸이 좁을 때(압축 모드) ──
   모바일뿐 아니라 전체 보기로 창을 좁혔을 때도 걸린다. 칸 폭이 92px 미만이면
   mcalendar.js가 .mc-grid--compact를 붙인다. 아이콘 줄바꿈을 막고(줄바꿈되면
   flex-shrink:0이라 칸을 뚫고 나가 잘린다) 일정은 글자 대신 색 막대만 남긴다.
   일정 내용은 칸을 눌러 여는 모달과 title 툴팁에 그대로 있다. */
/* 43px 칸의 세로 예산은 34.6px뿐 — 날짜 13 + 막대 4 + 아이콘 14 + 간격 2 = 33으로 맞춘다.
   14px면 360px 화면에서도 아이콘이 한 줄에 2개 들어간다(15px면 1개). */
.mc-grid--compact .mc-cell { gap: 1px; padding: 4px; }
.mc-grid--compact .mc-cell__d { font-size: .78rem; line-height: 1; }
.mc-grid--compact .mc-cell__icons { flex-wrap: nowrap; gap: 2px; }
.mc-grid--compact .mc-cell__icons img { width: 14px; height: 14px; }
.mc-grid--compact .mc-cell__more { font-size: .62rem; }
/* 색 막대는 세로로 쌓으면 개수만큼 넘치므로 가로로 나눠 한 줄에 담는다.
   flex-shrink:0이 없으면 칸이 빠듯할 때 이 줄이 0으로 짓눌려 막대가 사라진다. */
.mc-grid--compact .mc-cell__evs {
  flex-direction: row; align-items: center; gap: 2px;
  flex-shrink: 0; height: 4px;
}
.mc-grid--compact .mc-cell__ev {
  flex: 1 1 0; min-width: 0; height: 4px;
  padding: 0; font-size: 0; line-height: 0; border-radius: 2px;
}
.mc-grid--compact .mc-cell__evs .mc-cell__more { display: none; }

/* 일정 입력 — 설명 → 시간 → 반복 → 색 → 버튼 순으로 한 항목씩 아래로 쌓는다.
   한 줄에 몰아넣으면 좁은 화면에서 서로 밀려 글씨가 잘린다. */
.mc-ev-form { display: flex; flex-direction: column; align-items: flex-start; gap: 16px; }
.mc-ev__text { width: 100%; }
.mc-ev__time { display: flex; align-items: center; gap: 6px; }
.mc-ev__ampm { width: 5.4em; }
.mc-ev__num { width: 3.4em; text-align: center; font-variant-numeric: tabular-nums; }
.mc-ev__colon { font-weight: 900; color: var(--text-dim); }
.mc-ev__color { display: flex; align-items: flex-end; gap: 10px; }
.mc-ev__btns { display: flex; gap: 8px; }
.mc-ev__add, .mc-ev__cancel { flex-shrink: 0; }
.mc-ev__repeat {
  display: flex; align-items: center; gap: 7px; cursor: var(--cur-pointer);
  font-size: .92rem; font-weight: 700; color: var(--text-sub);
}
.mc-ev__repeat input { accent-color: var(--primary); width: 16px; height: 16px; }
.mc-ev__repeat b { color: var(--text-dim); font-weight: 800; }

/* 색 고르기 — 위 사각형은 채도/명도, 아래 띠는 색상 */
.mc-pick { display: flex; flex-direction: column; gap: 6px; width: 150px; }
.mc-pick__sv {
  --mc-hue: #ff0000;
  position: relative; height: 76px; border-radius: var(--radius-sm);
  border: 1px solid var(--border); cursor: crosshair; touch-action: none;
  background:
    linear-gradient(to top, #000, transparent),
    linear-gradient(to right, #fff, var(--mc-hue));
}
.mc-pick__hue {
  position: relative; height: 13px; border-radius: 999px;
  border: 1px solid var(--border); cursor: var(--cur-pointer); touch-action: none;
  background: linear-gradient(to right,
    #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%);
}
.mc-pick__dot, .mc-pick__hdot {
  position: absolute; pointer-events: none;
  border: 2px solid #fff; border-radius: 50%;
  box-shadow: 0 0 0 1px rgba(0,0,0,.55);
}
.mc-pick__dot { width: 12px; height: 12px; transform: translate(-50%, -50%); }
.mc-pick__hdot { width: 13px; height: 13px; top: 50%; transform: translate(-50%, -50%); }
.mc-pick__out { display: flex; flex-direction: column; gap: 6px; }
.mc-pick__prev {
  width: 42px; height: 42px; border-radius: var(--radius-sm);
  border: 1px solid var(--border);
}
.mc-pick__val { font-size: .78rem; font-weight: 700; color: var(--text-sub); white-space: nowrap; }

.mc-logrow__chip { width: 14px; height: 26px; border-radius: 4px; flex-shrink: 0; }
.mc-logrow__time { font-size: .86rem; font-weight: 800; color: var(--text-sub); flex-shrink: 0; }

/* 아이템 고르기 */
.mc-cat { display: flex; flex-direction: column; gap: 7px; margin-bottom: 12px; }
.mc-cat__title { font-size: .92rem; font-weight: 800; color: var(--text-sub); }
.mc-itemlist { display: flex; flex-wrap: wrap; gap: 8px; }
.mc-item { position: relative; display: block; line-height: 0; }
.mc-item img {
  width: 46px; height: 46px; object-fit: contain; padding: 5px;
  background: var(--bg3); border: 1px solid var(--border);
  border-radius: var(--radius-sm); transition: .12s;
}
.mc-item:hover img { border-color: var(--primary); background: rgba(var(--hue),.14); }
.mc-item:active img { transform: scale(.93); }
/* 이름은 body 직속 .mc-tip이 대신 띄운다 (모달 스크롤 영역에 잘리지 않게) */
.mc-item__name { display: none; }

.mc-tip {
  position: fixed; left: 0; top: 0; z-index: 2000;
  padding: 6px 12px; border-radius: 8px;
  background: var(--bg2); border: 2px solid var(--border-hl, var(--primary));
  box-shadow: 0 5px 18px rgba(0,0,0,.5);
  font-size: .92rem; font-weight: 800; line-height: 1.25; color: var(--text);
  white-space: nowrap; pointer-events: none;
  opacity: 0; visibility: hidden; transition: opacity .13s;
}
.mc-tip.on { opacity: 1; visibility: visible; }

/* 추가됐다는 걸 알려주는 토스트 */
.mc-toasts {
  position: fixed; left: 50%; bottom: 32px; transform: translateX(-50%);
  z-index: 2100; display: flex; flex-direction: column; align-items: center; gap: 8px;
  pointer-events: none;
}
.mc-toast {
  padding: 11px 22px; border-radius: 999px;
  background: var(--bg2); border: 2px solid var(--primary);
  box-shadow: 0 6px 24px rgba(0,0,0,.5);
  font-size: .98rem; font-weight: 800; color: var(--text);
  white-space: nowrap;
  animation: mcToastIn .18s cubic-bezier(.2,.8,.2,1);
}
.mc-toast.out { opacity: 0; transform: translateY(6px); transition: opacity .3s, transform .3s; }
@keyframes mcToastIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

/* 기록 목록 */
.mc-log { display: flex; flex-direction: column; gap: 6px; }
.mc-logrow {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 10px; background: var(--bg3);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.mc-logrow__item { width: 30px; height: 30px; object-fit: contain; flex-shrink: 0; }
.mc-logrow__name { font-size: .94rem; font-weight: 700; flex: 1; min-width: 0; }
.mc-logrow__del, .mc-logrow__edit {
  width: 26px; height: 26px; border-radius: 50%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  color: var(--text-dim); transition: .15s; font-size: .9rem;
}
.mc-logrow__del:hover { background: var(--danger-l); color: var(--danger); }
.mc-logrow__edit:hover { background: rgba(var(--hue-l),.15); color: var(--primary); }
/* 지금 폼에 올라와 수정 중인 항목이라는 걸 표시 */
.mc-logrow--editing { border-color: var(--primary); background: rgba(var(--hue-l),.08); }

@media (max-width: 768px) {
  .mc-cell__icons img { width: 14px; height: 14px; }
  .mc-cell__ev { font-size: .58rem; padding: 0 3px; }
  .mc-item img { width: 40px; height: 40px; }
  .mc-ev-form { gap: 10px; }
  .mc-ev__text { flex-basis: 100%; }
}

/* ── 첫 방문 공지 카드 ── */
.modal__title.modal__title--notice { font-size: 1.4rem; font-weight: 900; letter-spacing: -.3px; }
.notice-day {
  display: flex; flex-direction: column; gap: 10px;
  padding-bottom: 14px; border-bottom: 1px solid var(--border);
}
.notice-day:last-child { padding-bottom: 0; border-bottom: none; }
.notice-item { display: flex; flex-direction: column; gap: 5px; }
.notice-item__head { font-size: 1.06rem; font-weight: 900; color: var(--text); }
.notice-item__desc { font-size: .95rem; line-height: 1.6; color: var(--text-sub); }
.notice-date { font-size: .88rem; font-weight: 800; color: var(--text-dim); }

.job-grid { display: grid; grid-template-columns: repeat(auto-fill,minmax(66px,1fr)); gap: 6px; max-height: 210px; overflow-y: auto; padding: 2px; }
.job-item {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 8px 4px; border-radius: var(--radius-sm);
  background: var(--bg3); cursor: var(--cur-pointer);
  font-size: .66rem; color: var(--text-sub); text-align: center; transition: .15s;
  border: 1px solid transparent;
}
.job-item:hover { border-color: var(--primary); color: var(--primary); }
.job-item.sel { background: rgba(var(--hue-l),.15); border-color: var(--primary); color: var(--primary); }
.job-item img { width: 52px; height: 52px; object-fit: contain; border-radius: 7px; }

/* 카드 배경 선택 그리드 — 파일이 없는 번호는 onerror 체인이 타일 자체를
   지워버리므로, 실제로 채워 넣은 개수만큼만 자동으로 줄어든다. */
.cardbg-grid { display: grid; grid-template-columns: repeat(auto-fill,minmax(92px,1fr)); gap: 8px; max-height: 320px; overflow-y: auto; padding: 2px; }
.cardbg-opt {
  aspect-ratio: 1/1; border-radius: var(--radius-sm);
  border: 2px solid var(--border); background: var(--bg3); overflow: hidden;
  cursor: var(--cur-pointer); padding: 0; transition: border-color .15s;
}
.cardbg-opt:hover { border-color: var(--border-hl); }
.cardbg-opt.sel { border-color: var(--primary); box-shadow: 0 0 0 1px var(--primary); }
.cardbg-opt img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cardbg-opt--none { display: flex; align-items: center; justify-content: center; font-size: .68rem; color: var(--text-sub); font-weight: 700; }

/* ── LOOKUP ── */
.lookup-box {
  background: var(--lookup-bg);
  border: 1px solid rgba(var(--hue-l),.25);
  border-radius: var(--radius); padding: 14px 16px;
  display: flex; flex-direction: column; gap: 10px;
}
.lookup-box__title { font-size: .8rem; font-weight: 800; color: var(--text); }
/* 서버 토글 (NA / EU) — 캐릭터 조회 창 */
.region-toggle { display: flex; gap: 0; margin: 12px 12px 6px; padding: 4px; background: rgba(255,255,255,.03); border-radius: 8px; overflow: hidden; border: 1.5px solid var(--border); align-self: flex-start; }
.region-toggle__btn { flex: 1; padding: 5px 18px; border-radius: var(--radius-pill); font-size: .78rem; font-weight: 700; letter-spacing: .6px; background: transparent; color: var(--text-sub); border: none; border-right: 1px solid var(--border); cursor: var(--cur-pointer); transition: all .15s; }
.region-toggle__btn:last-child { border-right: none; }
.region-toggle__btn.active { background: var(--primary); color: #fff; box-shadow: 0 3px 12px rgba(0,0,0,.4); text-shadow: 0 0 8px rgba(var(--star),.4); }
:root[data-theme="light"] .region-toggle__btn.active { background: var(--btn); color: var(--on-btn); box-shadow: var(--btn-shadow); text-shadow: none; }
.region-toggle__btn:hover:not(.active) { background: rgba(var(--hue),.1); color: var(--text); }

.lookup-box__row { display: flex; gap: 8px; }
.lookup-box__row .inp { flex: 1; }
.lookup-box__row .sbtn { flex-shrink: 0; padding: 9px 16px; }
.lookup-box__note { font-size: .75rem; color: var(--text-sub); margin-top: 8px; }
.lookup-box__result:empty { display: none; }
.char-manual-sep { display: flex; align-items: center; gap: 10px; margin: 16px 0 12px; font-size: .78rem; color: var(--text-sub); }
.char-manual-sep::before, .char-manual-sep::after { content: ''; flex: 1; height: 1px; background: var(--border); }
.char-manual .job-grid { margin-top: 8px; }
.lk-err { font-size: .8rem; color: var(--danger); font-weight: 600; }
.lk-load { font-size: .8rem; color: var(--text-sub); }
.lk-card {
  display: flex; gap: 12px; align-items: center;
  background: var(--bg3); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 10px 12px;
}
.lk-card__av { width: 54px; height: 54px; object-fit: contain; flex-shrink: 0; }
.lk-card__info { display: flex; flex-direction: column; gap: 2px; }
.lk-card__name { font-size: .9rem; font-weight: 800; color: var(--text); }
.lk-card__job {
  font-size: .7rem; font-weight: 700; color: var(--primary);
  background: rgba(var(--hue-l),.15); padding: 2px 8px;
  border-radius: 99px; margin-left: 4px;
  border: 1px solid rgba(var(--hue-l),.25);
}
.lk-card__meta { font-size: .74rem; color: var(--text-sub); }
.lk-card__exp { font-size: .72rem; color: var(--text-sub); font-weight: 700; }

/* ── 캐릭터 정보 패널 ── */
.ci-empty {
  text-align: center; color: var(--text-sub); padding: 60px;
  font-size: .92rem; background: var(--bg-card);
  border: 1px solid var(--border); border-radius: var(--radius);
}
/* min-width:0 이 없으면 긴 직업명이 칸을 밀어내 카드 밖으로 잘려 나간다 */
/* 주간 합산 토글이 보스 계산기로 빠지면서 줄이 하나 줄었다. 카드가 전체적으로
   작아진 김에(캐릭터 그림을 96px로 고정한 뒤) 안쪽 여백·글자도 같이 줄인다 —
   특히 모바일은 카드 폭이 좁아 cqw 기여가 작아서 세로 길이가 유독 길어 보였다. */
.ci-card__body { padding: 9px 11px; display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.ci-card__nameline { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; min-width: 0; }
.ci-card__nameline > div { min-width: 0; }
/* 직업 일러스트는 투명한 곳이 많아 밝은 그림이 카드 바탕에 묻힌다 → 테두리와 옅은 바탕으로 칸을 잡는다.
   색은 두 테마 모두 화이트 모드 금색 --border-hl·--primary-l 값
   카드 폭(cqw) 기준으로 크기를 잡아 카드가 커지면 아이콘도 함께 커진다 */
.ci-jobicon { width: clamp(36px, 13cqw, 64px); height: clamp(36px, 13cqw, 64px); object-fit: contain; border-radius: 9px; border: 1px solid rgba(184,134,11,.6); background: rgba(184,134,11,.13); flex-shrink: 0; }
.ci-card__name { font-size: clamp(.8rem, .6rem + 1.8cqw, 1.25rem); font-weight: 900; letter-spacing: -.2px; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ci-card__job { font-size: clamp(.6rem, .46rem + .8cqw, .88rem); color: var(--text-sub); font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ci-card__meta {
  display: flex; align-items: center; justify-content: space-between;
  gap: 6px; flex-wrap: wrap; min-width: 0;
  border-top: 1px solid var(--border); padding-top: 6px;
}
.ci-lv { font-size: clamp(.7rem, .52rem + 1.3cqw, 1.1rem); font-weight: 900; color: var(--accent); text-shadow: 0 0 8px rgba(var(--star),.35); }
.ci-server { display: flex; align-items: center; gap: 4px; font-size: clamp(.6rem, .46rem + .8cqw, .88rem); font-weight: 700; color: var(--text-sub); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ci-servericon { width: clamp(18px, 5.5cqw, 32px); height: clamp(18px, 5.5cqw, 32px); object-fit: contain; }
.ci-rank-row { display: flex; justify-content: space-between; align-items: center; gap: 8px; min-width: 0; padding: 10px 0; border-bottom: 1px solid var(--border); font-size: .86rem; }
.ci-rank-row:last-child { border-bottom: none; }
.ci-rank-row span { color: var(--text-sub); font-weight: 600; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ci-rank-row b { font-weight: 900; color: var(--text); font-variant-numeric: tabular-nums; flex-shrink: 0; }
.ci-income-done { font-style: normal; color: var(--text-dim); font-weight: 700; }

/* 좌측 카드 하단 — 랭킹(있으면) + 이번 주 예상 수익 */
/* 위 선과 같이 글자 칸 안쪽에만 선을 긋도록 좌우는 padding 대신 margin으로 띄운다 */
.ci-card__ranks { margin: 0 11px; padding: 5px 0 7px; border-top: 1px solid var(--border); align-self: end; min-width: 0; }
.ci-card__ranks .ci-rank-row { padding: 2px 0; font-size: clamp(.62rem, .46rem + .9cqw, .95rem); }

/* ── TOAST ── */
.toast {
  position: fixed; left: 50%; bottom: 32px;
  transform: translateX(-50%) translateY(24px);
  /* 버튼과 같은 한 색. 그라데이션은 쓰지 않는다 */
  background: var(--btn); color: var(--on-btn); border: 1px solid var(--btn-border);
  padding: 12px 24px; border-radius: 12px;
  box-shadow: var(--shadow-lg);
  font-size: .88rem; font-weight: 700;
  z-index: 2000; opacity: 0; pointer-events: none;
  transition: opacity .25s, transform .25s;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* ── 해방 설정 카드 ── */
.gen-cfg-card{
  display:flex;gap:16px;align-items:center;
  background:var(--grad-card);
  border:1.5px solid rgba(var(--hue),.25);
  border-radius:16px;padding:18px;
  box-shadow:0 4px 20px rgba(0,0,0,.4);
  transition:.3s;
  position:relative;overflow:hidden;
  /* overflow:hidden인 flex 아이템의 자동 최소폭은 min-content가 아니라 0이라
     min-width을 명시하지 않으면 좁은 화면에서 이미지가 잘릴 정도로 짜부라진다 */
  flex:1 1 180px; min-width:180px;
}
.gen-cfg-card::before{
  content:'';position:absolute;inset:0;
  background:radial-gradient(ellipse 80% 60% at 0% 0%,rgba(var(--star),.06) 0%,transparent 70%);
  pointer-events:none;
}
.gen-cfg-card--pass{border-color:rgba(var(--star),.2)}
.gen-cfg-card--pass.on{
  border-color:rgba(var(--star),.6);
  background-image:linear-gradient(120deg,rgba(var(--star),.22),rgba(var(--hue),.28),rgba(var(--star),.22));
  /* 움직이는 반짝임 대신 정적인 금빛 글로우 */
  box-shadow:0 0 40px rgba(var(--star),.28),0 0 14px rgba(var(--star),.35),0 4px 20px rgba(0,0,0,.5);
}
.gen-cfg-card--pass.on .gen-cfg-card__img{filter:drop-shadow(0 0 8px rgba(var(--star),.65))}
.gen-cfg-card--pass.on::before{background:radial-gradient(ellipse 100% 80% at 0% 0%,rgba(var(--star),.15) 0%,transparent 65%)}
/* ★ 라이트 모드에서 단색으로 보이던 이유: 위 그라디언트가 --hue를 쓰는데
   라이트 테마의 --hue는 금색(184,134,11)이라, 양 끝 금색과 섞여 세 스톱이
   전부 비슷한 금색이 된다. 다크는 --hue가 보라(147,113,225)라 대비가 생겼던 것.
   라이트에선 밝기 차가 분명한 금색 계열로 다시 짜고 알파도 올린다. */
:root[data-theme="light"] .gen-cfg-card--pass.on{
  background-image:linear-gradient(120deg,rgba(214,160,20,.42) 0%,rgba(255,231,150,.9) 45%,rgba(214,160,20,.42) 100%);
  border-color:rgba(186,138,16,.75);
  box-shadow:0 0 34px rgba(var(--star),.5),0 0 12px rgba(214,160,20,.4),0 4px 20px rgba(120,95,20,.15);
}
:root[data-theme="light"] .gen-cfg-card--pass.on::before{
  background:radial-gradient(ellipse 100% 80% at 0% 0%,rgba(255,255,255,.55) 0%,transparent 65%);
}
/* ★ 아이콘 자리를 고정 폭으로 잡는다. 아이콘 원본이 33x33 / 44x32 / 37x37 / 34x34로
   가로가 제각각이라, 자리 폭을 내용에 맡기면 카드마다 제목 시작점이 달라진다
   (제네시스 패스가 제일 넓어서 혼자 밀려 보였다).
   가장 큰 것에 맞춘 44x37 자리에 object-fit:none으로 두면 그림은 원본 크기 그대로
   가운데 놓이면서(확대·축소 없음) 글자 시작점은 전부 같아진다. */
.gen-cfg-card__img{
  flex:none;width:44px;height:37px;object-fit:none;
  filter:drop-shadow(0 0 10px rgba(var(--star),.3))
}
.gen-cfg-card__body{flex:1;display:flex;flex-direction:column;gap:10px;min-width:0}
.gen-cfg-card__title{font-size:.95rem;font-weight:900;color:var(--text);letter-spacing:.3px}
.gen-cfg-card--pass .gen-cfg-card__title{color:var(--text)}

/* gen-switch 토글 */
.gen-switch{display:flex;align-items:center;gap:8px;font-size:.83rem;cursor:var(--cur-pointer);padding:7px 0;color:var(--text)}
.gen-switch input{width:15px;height:15px;accent-color:var(--primary)}
.gen-pass-toggle{gap:12px;padding:0}
.gen-pass-toggle input{position:absolute;opacity:0;width:0;height:0}
.gen-switch__track{width:42px;height:24px;border-radius:99px;background:var(--bg2);border:1.5px solid var(--border);position:relative;flex-shrink:0;transition:.2s}
.gen-pass-toggle input:checked ~ .gen-switch__track{background:var(--accent);border-color:var(--accent)}
.gen-switch__thumb{position:absolute;top:3px;left:3px;width:16px;height:16px;border-radius:50%;background:#fff;transition:.2s;box-shadow:0 1px 4px rgba(0,0,0,.4)}
.gen-pass-toggle input:checked ~ .gen-switch__track .gen-switch__thumb{transform:translateX(18px)}
.gen-switch__label{font-size:.82rem;font-weight:800;color:var(--text-sub)}
.gen-pass-toggle input:checked ~ .gen-switch__label{color:var(--accent)}
.gen-bosses{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:10px}
.gen-boss{display:flex;gap:12px;align-items:stretch;background:var(--bg3);border-radius:var(--radius-sm);padding:10px 14px;border:1.5px solid transparent;transition:.15s}
.gen-boss .boss-thumb{width:64px;height:64px;border-radius:8px;overflow:hidden;flex-shrink:0;align-self:center}
.gen-boss .boss-thumb img{width:100%;height:100%;object-fit:cover;filter:none}
.gen-boss.on{border-color:var(--success);background:var(--success-l)}
.gen-boss__body{flex:1;display:flex;flex-direction:column;gap:5px;min-width:0}
.gen-boss__top{display:flex;align-items:center;gap:6px}
.gen-boss__name{font-size:.9rem;font-weight:700;color:var(--text)}

/* ── 해방 계산기 새 레이아웃 ── */
/* minmax(0,1fr) 필수 — 1fr만 쓰면 트랙 최소폭이 auto(콘텐츠 기준)라
   왼쪽 콘텐츠가 넓을 때 그리드 자체가 오른쪽으로 넘친다 */
.gen-main-layout{display:grid;grid-template-columns:minmax(0,1fr) 320px;gap:16px;align-items:start}
.gen-left{display:flex;flex-direction:column;gap:14px}
.gen-inputs{display:flex;flex-direction:column;gap:0}
/* flex-wrap 없으면 768~900px대에서 두 카드가 짜부라짐 → 공간 부족 시 줄바꿈 */
.gen-input-row{display:flex;gap:12px;align-items:flex-end;flex-wrap:wrap}
/* ★ flex:1은 flex-basis가 0이라, wrap이 걸려 있어도 브라우저가 "폭 0까지 줄이면
   다 들어간다"고 계산해서 줄바꿈을 안 하고 칸을 짓눌러 버린다. 그러면 라벨이
   "일일 퀘스트 지 / 역"처럼 쪼개진다. min-width가 있어야 실제로 다음 줄로 넘어간다. */
.gen-input-row .field{flex:1;min-width:150px;display:flex;flex-direction:column;gap:5px}
.gen-inp{font-size:.88rem!important}

/* 보스 카드 새 구조 */
.gen-boss__row2{display:flex;align-items:center;gap:6px}
.gen-boss__diff{width:100%;flex:1;font-size:.76rem;padding:4px 7px}
.gen-boss__row3{display:flex;align-items:center;justify-content:space-between;gap:6px;margin-top:2px}
.gen-boss__ck{display:flex;align-items:center;gap:6px;font-size:.78rem;font-weight:700;color:var(--text-sub);cursor:var(--cur-pointer);user-select:none}
.gen-boss__ck input{width:15px;height:15px;accent-color:var(--success);cursor:var(--cur-pointer);flex-shrink:0}
.gen-boss__trace{font-size:.82rem;font-weight:800;color:var(--text-dim)}
.gen-boss__trace.on{color:var(--success)}

/* 우측 통계 패널
   .card{position:relative}가 이후에 선언되어 있어 같은 클래스 하나짜리
   명세도로는 소스 순서상 sticky를 덮어써 버린다 → 두 클래스 선택자로 명세도를 올림 */
.gen-stat-panel.card{display:flex;flex-direction:column;position:sticky;top:70px}
.gen-date-wrap{margin-top:20px;text-align:center;background:var(--bg3);border-radius:var(--radius-sm);padding:14px 12px}
.gen-date-label{font-size:.78rem;font-weight:700;color:var(--text-sub);margin-bottom:6px}
.gen-date-big{font-size:1.7rem;font-weight:900;color:var(--primary);letter-spacing:.5px}
.gen-res-row{display:flex;justify-content:space-between;align-items:center;font-size:.82rem;font-weight:600;padding:7px 0;border-bottom:1px solid var(--border);color:var(--text-sub)}
.gen-res-row b,.gen-res-val{font-weight:900;color:var(--text);font-size:.88rem}
.gen-res-total{color:var(--text)!important;font-size:.88rem!important}
.gen-res-total b{color:var(--primary)!important;font-size:.95rem!important}
.gen-res-accent b{color:var(--gold)!important}
.gen-res-divider{height:10px}

/* ── 스타포스 내 메소 입력 ── */
.sf-chart-card { display: flex; flex-direction: column; }
.sf-chart-header { display: flex; align-items: baseline; gap: 10px; margin-bottom: 10px; }
.sf-chart-lbl { font-size: .8rem; font-weight: 700; color: var(--text-sub); }
.sf-chart-box { position: relative; width: 100%; height: 320px; }
.sf-chart-box canvas { position: absolute; inset: 0; width: 100% !important; height: 100% !important; }
.sf-my-meso{margin-top:14px;padding:12px 14px;background:var(--bg3);border-radius:var(--radius-sm);border:1px solid var(--border)}
.sf-bidir{display:flex;align-items:flex-end;gap:10px}
.sf-bidir__field{display:flex;flex-direction:column;gap:4px;flex:1}
.sf-bidir__lbl{font-size:.75rem;font-weight:700;color:var(--text-sub)}
.sf-bidir__inp{width:100%;box-sizing:border-box}
.sf-bidir__arrow{font-size:1.2rem;color:var(--text-sub);padding-bottom:6px;flex-shrink:0}
.sf-my-result{display:flex;align-items:center;gap:8px;margin-top:10px;font-size:.9rem;font-weight:700}
.sf-my-result__sep{color:var(--text-sub)}
.sf-my-result__meso{color:var(--text)}
.sf-my-result__tag{padding:4px 12px;border-radius:99px;font-size:.85rem;font-weight:800;background:var(--bg2);color:var(--text-sub)}
.sf-my-result__tag.lucky{background:var(--success-l);color:var(--success)}
.sf-my-result__tag.unlucky{background:rgba(240,80,96,.15);color:var(--danger)}

/* ── utils ── */
.mt8  { margin-top: 8px; }
.mt16 { margin-top: 16px; }

/* ── 캐릭터 그리드 (캐릭터 정보 탭) ── */
/* 가로형 카드 2열 고정 → 캐릭터가 늘면 아래로 행이 추가된다.
   카드는 창 너비를 꽉 채우며, 일러스트가 정사각 비율이라 폭이 커지면 높이도 함께 커진다. */
/* 일러스트를 원본 크기(96px)로 고정하면서 카드도 그에 맞게 줄였다.
   4열 상한은 그대로 — 270px 카드 5개(5*270+4*10=1390)보다 작게 잡아야 4열에서 멈춘다. */
/* grid-auto-rows 1fr: 랭킹이 없는 카드도 가장 높은 카드와 같은 높이로 */
.cg-grid {
  display:grid; grid-template-columns:repeat(auto-fill,minmax(270px,1fr)); grid-auto-rows: 1fr;
  gap:10px; padding:8px 0 12px;
  max-width: 1360px; /* 카드 폭이 무한정 안 늘어나게 4열까지만 — 넘는 공간은 우측 여백으로 남긴다(가운데 정렬 X) */
}
.cg-card {
  position: relative;
  background: var(--panel-veil);
  border: 1px solid rgba(var(--hue),.2);
  border-radius: var(--radius);
  overflow: hidden; cursor: var(--cur-pointer);
  /* 행을 명시해야 일러스트의 grid-row:1/-1 이 두 행을 걸친다 */
  /* 일러스트 칼럼은 112px 고정 — 넥슨 아바타가 96px뿐이라 칼럼을 카드 폭에 따라
     늘리면 그만큼 확대돼서 흐려진다(예전엔 최대 240px까지 늘어나 1.47배였다). */
  display: grid; grid-template-columns: 112px 1fr; grid-template-rows: 1fr auto; align-items: stretch;
  transition: border-color .18s, transform .2s cubic-bezier(.2,.8,.2,1);
  /* 카드 폭 기준 컨테이너 쿼리 단위(cqw) → 카드가 커지면 글씨/아이콘도 함께 커진다 */
  container-type: inline-size;
}
.cg-card:hover { border-color:rgba(var(--hue-l),.5); transform: translateY(-3px); }
/* 카드 이미지로 저장 버튼 — 평소엔 옅게, 카드 hover 시에만 또렷하게 (카드 정보를 안 가리도록) */
.cg-card__save {
  position: absolute; top: 6px; left: 6px; z-index: 2;
  padding: 3px 8px; border-radius: 4px;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,.45); color: #fff; font-size: .68rem; font-weight: 600; white-space: nowrap;
  opacity: 0; transition: opacity .15s, background .15s;
}
.cg-card:hover .cg-card__save { opacity: 1; }
.cg-card__save:hover { background: rgba(var(--hue),.7); }
.cg-card__save:disabled { opacity: .6; cursor: var(--cur-default); }
/* 카드 순서 바꾸기 화살표. 일러스트 칸 아래 양 끝에 둔다. 사이드바 즐겨찾기 화살표 BtUP을 90도 돌린 그림이고,
   맨 앞 카드의 왼쪽·맨 뒤 카드의 오른쪽은 회색으로 막는다. 저장 버튼처럼 카드에 마우스를 올렸을 때만 보인다 */
.cg-mv {
  position: absolute; left: 0; bottom: 6px; z-index: 2; width: 112px; padding: 0 6px;
  display: flex; justify-content: space-between; pointer-events: none;
  opacity: 0; transition: opacity .15s;
}
.cg-card:hover .cg-mv { opacity: 1; }
@media (hover: none) { .cg-mv { opacity: 1; } }
.cg-mv__b {
  position: relative; width: 12px; height: 12px; pointer-events: auto;
  background: no-repeat center / 12px 12px; image-rendering: pixelated; cursor: var(--cur-pointer);
}
.cg-mv__b::after { content: ''; position: absolute; inset: -6px; }
.cg-mv__b--left { background-image: url(images/icons/move_left.png); }
.cg-mv__b--left:hover { background-image: url(images/icons/move_left_hover.png); }
.cg-mv__b--right { background-image: url(images/icons/move_right.png); }
.cg-mv__b--right:hover { background-image: url(images/icons/move_right_hover.png); }
.cg-mv__b--left.is-off { background-image: url(images/icons/move_left_off.png); cursor: var(--cur-default); }
.cg-mv__b--right.is-off { background-image: url(images/icons/move_right_off.png); cursor: var(--cur-default); }
.cg-card--active {
  border-color: var(--primary);
  box-shadow: 0 0 0 1px #f5c842;
}
/* 일러스트는 왼쪽에서 카드 전체 높이를 차지.
   aspect-ratio로 카드 폭을 따라가게 두면 그림이 늘어나므로 칼럼 폭(112px)에만 맞춘다. */
.cg-portrait {
  grid-row:1 / -1; width:112px;
  background: transparent;
  display:flex; align-items:flex-end; justify-content:center;
  overflow:hidden; position:relative; flex-shrink:0;
}
/* 넥슨 캐릭터 이미지는 96x96 원본 → 박스 너비에 맞춰 그려진다.
   확대(transform)는 위쪽이 잘리므로 쓰지 않고 박스 크기로 키운다.
   바닥 여백은 margin-bottom으로 준다 — padding(부모)은 width/height %의 기준이
   갈라져 캐릭터가 작아졌고, 3-value object-position은 문법 무효라 무시됐음
   (넥슨 아바타가 96x96 정사각이라 애초에 object-position이 먹을 레터박스도 없었음). */
/* %가 아니라 96px 고정 — 92%(112px 기준 103px)로 두면 96px 원본을 1.07배 늘리게 된다.
   image-rendering:pixelated로 그 확대분마저 최대한 선명하게 그린다. */
.cg-portrait img:not(.portrait-bg) { width:96px; height:96px; object-fit:contain; object-position:bottom center; margin-bottom:4px; position:relative; z-index:1; image-rendering:pixelated; }
/* 기본 이미지(default.png)는 넥슨 스크린샷과 비율이 달라 실제 캐릭터보다 크게 보임 → 축소해서 중앙 배치 */
.cg-portrait--no img:not(.portrait-bg) { width: 96px; height: 96px; object-position: bottom center; margin-bottom: 4px; }

/* ── 버스 5% 참조 패널 ── */
.bus-panel {
  background: var(--panel-veil);
  border: 1px solid rgba(var(--hue),.25);
  border-radius: var(--radius);
  margin-bottom: 20px;
  overflow: hidden;
}
.bus-panel__head {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 18px;
  background: rgba(var(--hue),.1);
  border-bottom: 1px solid rgba(var(--hue),.15);
}
.bus-panel__title { font-size: .95rem; font-weight: 800; color: var(--accent); }
.bus-table-wrap   { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* 빈 상태 */
.bus-empty {
  padding: 20px 18px;
  color: var(--text-sub); font-size: .82rem; text-align: center;
}
.bus-empty b { color: var(--text); }

/* 테이블 */
.bus-tbl { width: 100%; border-collapse: collapse; font-size: .82rem; }
.bus-tbl thead tr { background: rgba(255,255,255,.03); }
.bus-tbl th {
  padding: 8px 14px; text-align: left;
  font-size: .73rem; font-weight: 700;
  color: var(--text-sub); letter-spacing: .4px;
  border-bottom: 1px solid rgba(var(--hue),.15);
}
.bus-tbl td { padding: 7px 14px; border-bottom: 1px solid rgba(255,255,255,.04); vertical-align: middle; }
.bus-tbl tr:last-child td { border-bottom: none; }
.bus-tbl tr:hover td { background: rgba(255,255,255,.03); }
.bus-boss-name { display: flex; align-items: center; gap: 8px; font-weight: 600; white-space: nowrap; }
.bus-boss-img  { width: 28px; height: 28px; object-fit: contain; border-radius: 4px; flex-shrink: 0; }
.bus-pct5 { text-align: right; color: var(--danger); font-variant-numeric: tabular-nums; font-size: .9rem; }
.bus-tbl th.bus-pct5 { text-align: right; }

/* 버스 패널 난이도 셀렉트 */
.bus-diff-sel {
  background: var(--bg2); border: 1px solid rgba(var(--hue),.3);
  color: var(--text); border-radius: 6px; padding: 3px 8px; font-size: .78rem;
  font-family: inherit; cursor: var(--cur-pointer);
}
.bus-diff-sel option { background: var(--bg2); color: var(--text); }

/* 버스 패널 제거 버튼 */
.bus-remove {
  color: var(--text-sub); font-size: .8rem; padding: 2px 7px;
  border: 1px solid rgba(255,255,255,.1); border-radius: 5px;
  transition: color .15s, border-color .15s;
}
.bus-remove:hover { color: var(--danger); border-color: var(--danger); }

/* 보스 카드 이름줄 (이름 + 토글 버튼) */
.bhp-name-row {
  display: flex; align-items: center; justify-content: space-between; gap: 6px;
  margin-bottom: 2px;
}

/* 버스 토글 스위치 (보스 카드 우측) */
.bus-toggle-wrap { display: inline-flex; align-items: center; cursor: var(--cur-pointer); flex-shrink: 0; }
.bus-toggle-input { display: none; }
.bus-toggle-track {
  position: relative; width: 34px; height: 18px;
  background: rgba(255,255,255,.12); border-radius: 9px;
  border: 1px solid rgba(var(--hue),.3);
  transition: background .2s, border-color .2s;
}
.bus-toggle-thumb {
  position: absolute; top: 2px; left: 2px;
  width: 12px; height: 12px; border-radius: 50%;
  background: #6b7280;
  transition: transform .2s, background .2s;
}
.bus-toggle-input:checked + .bus-toggle-track {
  background: rgba(var(--hue),.5); border-color: var(--primary);
}
.bus-toggle-input:checked + .bus-toggle-track .bus-toggle-thumb {
  transform: translateX(16px); background: #fff;
}

/* ── 패밀리어 카드 그림 ──
   픽셀아트라 크기를 줄이면 뭉개진다. 원본 크기(164px) 그대로 쓰고,
   화면이 좁을 때만 줄어들게 max-width만 건다. */
.fam-cardcol { display: flex; flex-direction: column; }
.fam-cardview { display: flex; justify-content: center; }
.fam-cardview img { width: 164px; max-width: 100%; height: auto; image-rendering: pixelated; }
.fam-cardview__lbl { margin-top: 8px; text-align: center; font-size: .82rem; font-weight: 800; }
.fam-cardview__lbl[data-grade="RARE"]   { color: var(--gt-rare); }
.fam-cardview__lbl[data-grade="EPIC"]   { color: var(--gt-epic); }
.fam-cardview__lbl[data-grade="UNIQUE"] { color: var(--gt-unique); }
.ru-now[data-grade="RARE"]   { color: var(--gt-rare); }
.ru-now[data-grade="EPIC"]   { color: var(--gt-epic); }
.ru-now[data-grade="UNIQUE"] { color: var(--gt-unique); }
.ru-now[data-grade="LEGENDARY"] { color: var(--gt-legendary); }
.ru-log-res { font-weight: 800; }
.ru-log-res.ok { color: var(--success); }
.ru-log-res.no { color: var(--danger); }

/* 소울 증폭 게이지 — 실패할수록 채워지다 가득 차면 다음 시도가 확정 성공 */
.soul-gauge { height: 8px; border-radius: 999px; background: var(--bg3); overflow: hidden; margin: 4px 0 10px; }
.soul-gauge__fill { height: 100%; background: var(--grad); transition: width .2s ease; }
.ru-log-pity { font-size: .68rem; font-weight: 800; color: var(--accent); border: 1px solid var(--accent); border-radius: 5px; padding: 0 5px; }

/* ── 패밀리어 ── */
/* 유효 옵션 표시. 줄 색은 .pot-line[data-grade]가 이미 등급별로 칠해준다. */
.fam-line__star { margin-right: 6px; color: #fff; text-shadow: 0 0 6px rgba(255,255,255,.7); }
.fam-log { display: flex; flex-direction: column; gap: 4px; margin-top: 10px; max-height: 420px; overflow-y: auto; }
.fam-log-row {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 6px 10px; border-radius: 8px; background: var(--bg2);
  font-size: .74rem;
}
.fam-log-row.is-hit { background: color-mix(in srgb, var(--accent) 14%, var(--bg2)); }
.fam-log-icon { width: 13px; height: 13px; flex-shrink: 0; image-rendering: pixelated; }
.fam-log-n { min-width: 42px; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.fam-log-line { font-weight: 700; }
.fam-log-line[data-grade="RARE"]   { color: var(--gt-rare); }
.fam-log-line[data-grade="EPIC"]   { color: var(--gt-epic); }
.fam-log-line[data-grade="UNIQUE"] { color: var(--gt-unique); }

/* ── 미스틱 프론티어 ── */
.fr-dice-row { display: flex; gap: 10px; }
.fr-dice { flex: 1; display: flex; flex-direction: column; gap: 6px; }
.fr-pass { margin-top: 10px; font-size: .86rem; font-weight: 800; text-align: center; }
.fr-pass.ok { color: var(--success); }
.fr-pass.no { color: var(--danger); }
/* 카드 3장을 나란히 — 실제 게임의 팀 편성 화면(이미지 위, 정보는 아래로 쌓이는 카드 3장)을 참고 */
/* minmax(0,1fr) — 그냥 1fr이면 칸의 최소 폭이 내용 길이라, 긴 잠재 문구가 들어오면
   칸이 늘어나면서 세 번째 카드가 화면 밖으로 밀려난다. */
.fr-team { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
@media (max-width: 640px) { .fr-team { grid-template-columns: minmax(0, 1fr); } }
.fr-slot {
  display: flex; flex-direction: column; align-items: center; gap: 8px; min-width: 0;
  padding: 10px; border-radius: var(--radius-sm); background: var(--bg2); border: 1px solid var(--border);
}
.fr-slot__field, .fr-slot .fr-dd, .fr-slot .sel { min-width: 0; max-width: 100%; }
/* 로로 카드는 픽셀아트라 원본(164px)에서 정수배로만 줄여야 안 뭉갠다 */
.fr-slot__img { width: 100%; max-width: 164px; height: auto; image-rendering: pixelated; }
.fr-slot__rank { width: 100%; }
.fr-slot__rank .sf-toggle { flex: 1; padding: 5px 0; font-size: .7rem; }
.fr-slot__field { width: 100%; }
.fr-slot__field-lbl { display: block; font-size: .68rem; font-weight: 800; color: var(--text-dim); margin-bottom: 5px; }

/* 고른 잠재가 지금 주사위에서 실제로 터졌는지 카드마다 알려주는 표시 */
.fr-line-state { display: block; font-size: .7rem; font-weight: 800; margin-top: 6px; min-height: 1em; }
.fr-line-state.ok { color: #2ecc71; }
.fr-line-state.no { color: var(--text-dim); }
/* 속성/타입 드롭다운 — 평소엔 접혀 있다가 누르면 그림 목록이 펼쳐진다 */
.fr-dd { position: relative; margin-top: 6px; }
.fr-dd__trigger {
  width: 100%; display: flex; align-items: center; gap: 8px;
  padding: 7px 10px; border-radius: 8px;
  background: var(--bg2); border: 1.5px solid var(--border); color: var(--text);
  font-size: .8rem; text-align: left; cursor: var(--cur-pointer);
}
.fr-dd__trigger:hover { border-color: var(--accent); }
.fr-dd__trigger img { width: 18px; height: 18px; object-fit: contain; flex: none; }
.fr-dd__trigger span:not(.fr-dd__caret) { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fr-dd__caret { flex: none; color: var(--text-dim); font-size: .7rem; }
/* display:flex가 class 특이도로 [hidden]의 기본 display:none을 덮어써서
   누르지 않아도 펼쳐진 채로 보이는 버그가 있었다 — [hidden]을 명시적으로 다시 막는다. */
.fr-dd__menu {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 20;
  max-height: 260px; overflow-y: auto;
  background: var(--bg2); border: 1.5px solid var(--border); border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,.25);
  display: flex; flex-direction: column; padding: 4px;
}
.fr-dd__menu[hidden] { display: none; }
.fr-dd__item {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 7px 8px; border-radius: 6px; background: transparent; color: var(--text);
  font-size: .8rem; text-align: left; cursor: var(--cur-pointer);
}
.fr-dd__item img { width: 18px; height: 18px; object-fit: contain; flex: none; }

/* 잠재 드롭다운 — 한 칸 안에서 조건 → 수치로 파고든다. 조건이 60개 가까이라 목록은 스크롤. */
.fr-dd--line .fr-dd__trigger { text-align: left; min-width: 0; }
.fr-ln-cur { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: .72rem; }
/* 펼친 목록은 칸 너비에 갇히지 않게 띄워서 넓게 — 문구가 길어 한 줄에 안 들어간다 */
.fr-dd--line { position: relative; }
.fr-dd__menu--line { position: absolute; left: 0; right: auto; z-index: 30; width: max-content; max-width: min(420px, 80vw); max-height: 260px; overflow-y: auto; min-width: 260px; }
/* 마지막 칸은 오른쪽 끝을 맞춰 펼친다 — 왼쪽 기준이면 화면 밖으로 넘어간다 */
.fr-slot:last-child .fr-dd__menu--line { left: auto; right: 0; }
/* 좁은 화면에선 넓힐 자리가 없다 — 칸 너비에 맞추고 문구를 여러 줄로 흘린다 */
@media (max-width: 640px) { .fr-dd__menu--line { width: 100%; max-width: 100%; } }
.fr-dd__trigger[data-empty] .fr-ln-cur { color: var(--text-dim); }
.fr-dd__menu--line .fr-dd__item { font-size: .72rem; text-align: left; white-space: normal; line-height: 1.35; }
.fr-dd__more { margin-left: auto; padding-left: 8px; color: var(--text-dim); flex: none; }
.fr-ln-back { font-weight: 800; color: var(--accent); position: sticky; top: 0; background: var(--bg2); z-index: 1; }

.fr-dd__item:hover { background: var(--bg3); }
.fr-dd__item.active { background: color-mix(in srgb, var(--accent) 20%, var(--bg2)); color: var(--accent); font-weight: 700; }
.fr-badges { display: flex; flex-direction: column; gap: 6px; }
.fr-badge {
  padding: 8px 12px; border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--accent) 12%, var(--bg2));
  border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
  font-size: .82rem; font-weight: 700; color: var(--text);
}
.fr-badge--empty { background: var(--bg2); border-color: var(--border); color: var(--text-sub); font-weight: 500; }

/* 덱 저장 — 캐릭터당 3칸. 캐릭터별이라는 게 한눈에 보이게 얼굴을 같이 띄운다. */
.fr-decks { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
/* 제목 줄 — 왼쪽 제목, 오른쪽 덱 칸 */
.fr-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.fr-deck__bar { display: flex; align-items: center; gap: 6px; margin-left: auto; }

.fr-deck__who { display: flex; align-items: center; gap: 8px; }
/* 넥슨이 주는 캐릭터 그림은 96×96이다. 크게 늘릴수록 흐려져서, 사이드바 캐릭터 카드와
   같은 정도(약 1.17배)까지만 키운다. 그 이상은 없는 픽셀을 만들어내는 것이라 뭉개진다. */
.fr-deck__face { width: 112px; height: 112px; object-fit: contain; flex: none; }
.fr-deck__whoBody { display: flex; flex-direction: column; gap: 2px; }
.fr-deck__name { font-size: .9rem; font-weight: 800; color: var(--accent); line-height: 1.2; }
.fr-deck__lv { font-size: .72rem; font-weight: 700; color: var(--text-dim); line-height: 1.2; }
.fr-deck__empty { font-size: .76rem; color: var(--text-dim); }
.fr-deck__slots { display: flex; gap: 4px; }
.fr-deck__slot {
  width: 30px; height: 30px; border-radius: 6px;
  font-size: .78rem; font-weight: 800;
  color: var(--text-dim); background: var(--bg2); border: 1px solid var(--border);
}
/* 내용이 있는 칸만 진하게 — 비었는지 찼는지 숫자만 보고 알 수 있어야 한다 */
.fr-deck__slot.filled { color: var(--text); border-color: rgba(var(--star),.55); }
.fr-deck__slot.sel { border-color: var(--accent); color: var(--accent); background: color-mix(in srgb, var(--accent) 16%, var(--bg2)); }
.fr-deck__slot:hover { border-color: var(--accent); }

/* 보너스 주사위 한 줄: 이름표 + 드롭다운(그림으로 고른다) */
.fr-bonus { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.fr-bonus__img { width: 26px; height: 26px; object-fit: contain; flex: none; }
.fr-bonus .fr-bonus__lbl { flex: none; width: 72px; font-size: .74rem; font-weight: 700; color: var(--text-dim); }
.fr-bonus .fr-bd { flex: 1; min-width: 0; }
/* 고른 주사위를 비우는 버튼. 안 고른 칸에서는 자리만 잡고 숨는다(줄이 안 흔들리게) */
.fr-bd-clear {
  flex: none; width: 24px; height: 24px; border-radius: 6px;
  font-size: 1rem; line-height: 1; color: var(--text-dim);
  background: transparent; border: 1px solid var(--border);
}
.fr-bd-clear:hover { color: #e5484d; border-color: #e5484d; }
/* 이름보다 그림을 보고 고르는 물건이라 목록 그림을 크게 준다 */
.fr-bd .fr-dd__menu--line .fr-dd__item img { width: 30px; height: 30px; }
.fr-bd .fr-dd__menu--line .fr-dd__item { gap: 8px; }
@media (max-width: 640px) {
  .fr-bonus .fr-bonus__lbl { width: 62px; }
}
#frBonusDice { display: flex; flex-direction: column; gap: 6px; }

/* ── 움직임 효과 ──
   전부 transform·opacity만 움직인다. 이 둘은 레이아웃·페인트를 다시 하지 않고 합성만 일어나
   가볍다. 배경 흐름·반짝임은 데스크톱에서만 돌고, 폰과 동작 줄이기 설정에서는 멈춘 그림이다.
   예전 별 캔버스는 매 프레임 그려서 무거웠다 — 여기서는 미리 칠한 층을 옮기기만 한다. */

/* 메뉴를 바꾸면 제목과 카드가 차례로 떠오른다. app.js의 navigateTo가 .sec--enter를 0.9초만 붙였다 떼서,
   그 뒤에 결과를 다시 그릴 때는 움직이지 않는다. backwards라 끝난 뒤에는 transform이 남지 않는다
   (남으면 안쪽 position:fixed 요소의 기준이 바뀐다) */
.sec--enter :is(.sec-head, .card, .cg-card, .bhp-card, .dt-card, .mx-layout, .fr-head) {
  animation: riseIn .5s cubic-bezier(.2,.8,.2,1) backwards;
}
.sec--enter :is(.card, .cg-card, .bhp-card, .dt-card):nth-child(2) { animation-delay: .06s; }
.sec--enter :is(.card, .cg-card, .bhp-card, .dt-card):nth-child(3) { animation-delay: .12s; }
.sec--enter :is(.card, .cg-card, .bhp-card, .dt-card):nth-child(4) { animation-delay: .18s; }
.sec--enter :is(.card, .cg-card, .bhp-card, .dt-card):nth-child(n+5) { animation-delay: .24s; }
@keyframes riseIn { from { opacity: 0; transform: translateY(18px); } }
/* 스크롤하면 떠오르기 — common.js revealOnScroll. transform을 쓰는 카드 hover와 겹치지 않게 translate로 움직인다 */
/* 이름 앞에 fx-를 붙인다. .rv는 헥사 계산기 결과 숫자 칸이 이미 쓰는 이름이라 겹쳐서 숫자가 숨었었다 */
.fx-rise { opacity: 0; translate: 0 24px; }
.fx-rise.fx-rise-in { opacity: 1; translate: 0 0; transition: opacity .5s ease, translate .6s cubic-bezier(.2,.8,.2,1); }
/* 제목 밑에 금빛 선이 그어진다 */
.sec-head { position: relative; }
.sec-head::after {
  content: ''; position: absolute; left: 0; bottom: -6px; width: min(320px, 55%); height: 2px; border-radius: 2px;
  background: linear-gradient(90deg, rgb(var(--star)), rgba(var(--hue-l),.85) 60%, transparent);
  transform-origin: left;
}
.sec--enter .sec-head::after { animation: lineDraw .7s .1s cubic-bezier(.2,.8,.2,1) backwards; }
@keyframes lineDraw { from { transform: scaleX(0); } }
/* 모달 뒤 막도 서서히 깔린다. 모달 자체는 .modal의 modalIn */
.overlay.open { animation: overlayIn .2s ease-out backwards; }
@keyframes overlayIn { from { opacity: 0; } }

/* 배경 — 보라·금빛 안개가 아주 천천히 흐르고, 별이 숨 쉬듯 반짝인다 */
body::before { content: ''; position: fixed; pointer-events: none; z-index: 0; }
body::before {
  inset: -20%;
  background:
    radial-gradient(38% 32% at 18% 22%, rgba(var(--hue),.18), transparent 70%),
    radial-gradient(30% 26% at 82% 18%, rgba(var(--star),.08), transparent 70%),
    radial-gradient(44% 38% at 66% 82%, rgba(var(--hue-d),.15), transparent 72%);
}
/* 네 갈래 반짝이 — 두 층에 나눠 서로 다른 박자로 깜빡여서, 별마다 따로 반짝이는 것처럼 보인다.
   .app 안의 z-index:-1이라 본문 뒤, 배경 안개 위에 깔린다 */
.app::before, .app::after {
  content: ''; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  --spark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 0C13 9 15 11 24 12C15 13 13 15 12 24C11 15 9 13 0 12C9 11 11 9 12 0Z' fill='%23e4bf56'/%3E%3C/svg%3E");
  --spark-w: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 0C13 9 15 11 24 12C15 13 13 15 12 24C11 15 9 13 0 12C9 11 11 9 12 0Z' fill='%23e4dcff'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  opacity: .25;
}
.app::before {
  background-image: var(--spark), var(--spark-w), var(--spark), var(--spark-w), var(--spark);
  background-position: 9% 14%, 47% 7%, 91% 22%, 72% 63%, 26% 88%;
  background-size: 14px, 9px, 11px, 12px, 8px;
}
.app::after {
  background-image: var(--spark-w), var(--spark), var(--spark-w), var(--spark), var(--spark-w);
  background-position: 33% 31%, 84% 79%, 61% 41%, 4% 57%, 96% 92%;
  background-size: 10px, 13px, 8px, 9px, 12px;
}
:root[data-theme="light"] .app::before, :root[data-theme="light"] .app::after { filter: brightness(.7) saturate(1.4); }
:root[data-theme="light"] body::before {
  background:
    radial-gradient(38% 32% at 18% 22%, rgba(var(--star),.24), transparent 70%),
    radial-gradient(30% 26% at 82% 18%, rgba(170,140,255,.18), transparent 70%),
    radial-gradient(44% 38% at 66% 82%, rgba(255,170,200,.16), transparent 72%);
}
/* 폰에서도 돈다 — 모두 합성만 일어나는 transform·opacity라 가볍고, 폰은 헤더 블러가 꺼져 있어
   배경이 움직여도 블러를 다시 계산하지 않는다 */
@media (prefers-reduced-motion: no-preference) {
  body::before { animation: bgDrift 30s ease-in-out infinite alternate; }
  .app::before { animation: sparkPulse 3.2s ease-in-out infinite alternate; }
  .app::after  { animation: sparkPulse 4.3s ease-in-out -2.1s infinite alternate; }
}
@keyframes bgDrift { to { transform: translate3d(6%, -4%, 0) rotate(8deg) scale(1.12); } }
@keyframes sparkPulse { from { opacity: .08; } to { opacity: .85; } }
/* 첫 로딩 화면 — 화면을 격자 무늬로 덮은 채 캐릭터가 통통 뛰고, 준비되면 투명도만 바꿔 걷힌다.
   (뮤즈대시 로딩 화면과 같은 구성: 덮개 · 가운데 캐릭터 · 아래 안내 글자) */
.boot {
  position: fixed; inset: 0; z-index: 3000;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px;
  background:
    linear-gradient(rgba(var(--hue-l),.08) 1px, transparent 1px) 0 0 / 44px 44px,
    linear-gradient(90deg, rgba(var(--hue-l),.08) 1px, transparent 1px) 0 0 / 44px 44px,
    radial-gradient(60% 50% at 50% 42%, rgba(var(--hue),.32), transparent 70%),
    var(--bg);
  transition: opacity .35s ease, visibility .35s;
}
.boot.is-done { opacity: 0; visibility: hidden; }
.boot__stage { position: relative; width: 176px; height: 176px; display: grid; place-items: center; }
/* 게임 이벤트 목록의 금색 별(43×38)을 원본 그대로 3배 — 정수배라 도트가 고르다 */
.boot__art {
  width: 129px; height: 114px; image-rendering: pixelated;
  filter: drop-shadow(0 10px 14px rgba(0,0,0,.4));
  animation: bootBob .9s cubic-bezier(.45,.05,.55,.95) infinite alternate;
}
/* 금빛 고리 — 원뿔 그라디언트를 가운데만 뚫어 테만 남기고 돌린다 */
.boot__ring {
  position: absolute; inset: 0; border-radius: 50%;
  background: conic-gradient(from 0deg, transparent 0 55%, rgba(var(--star),.95) 76%, rgba(var(--hue-l),.9) 90%, transparent);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 4px), #000 calc(100% - 3px));
          mask: radial-gradient(farthest-side, transparent calc(100% - 4px), #000 calc(100% - 3px));
  animation: bootSpin 1.6s linear infinite;
}
.boot__spark { position: absolute; color: rgb(var(--star)); font-size: 18px; line-height: 1; text-shadow: 0 0 10px rgba(var(--star),.8); animation: bootTwinkle 1.4s ease-in-out infinite; }
.boot__spark--1 { top: 8px; right: 16px; }
.boot__spark--2 { bottom: 20px; left: 4px; font-size: 13px; animation-delay: .45s; }
.boot__spark--3 { top: 44px; left: -4px; font-size: 10px; animation-delay: .9s; }
.boot__name {
  font-size: 1.3rem; font-weight: 900; letter-spacing: 1px;
  background: linear-gradient(90deg, rgb(var(--star)), #cac0f2);
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}
.boot__txt { display: flex; align-items: baseline; font-size: .82rem; font-weight: 700; letter-spacing: 2px; color: var(--text-sub); }
.boot__dots { display: inline-flex; gap: 3px; margin-left: 5px; }
.boot__dots i { width: 4px; height: 4px; border-radius: 50%; background: currentColor; animation: bootDot 1s ease-in-out infinite; }
.boot__dots i:nth-child(2) { animation-delay: .15s; }
.boot__dots i:nth-child(3) { animation-delay: .3s; }
@keyframes bootBob { from { transform: translateY(4px) scale(1, .97); } to { transform: translateY(-10px); } }
@keyframes bootSpin { to { transform: rotate(360deg); } }
@keyframes bootTwinkle { 0%, 100% { opacity: .2; transform: scale(.7); } 50% { opacity: 1; transform: scale(1.1) rotate(20deg); } }
@keyframes bootDot { 0%, 100% { opacity: .25; transform: none; } 50% { opacity: 1; transform: translateY(-3px); } }

/* 섹션 제목 끝의 별 — 천천히 돌며 숨 쉰다 */
.sec-title::after {
  content: '✦'; display: inline-block; margin-left: .35em; vertical-align: .18em;
  font-size: .5em; color: rgb(var(--star)); -webkit-text-fill-color: rgb(var(--star)); text-shadow: 0 0 10px rgba(var(--star),.7);
}
:root[data-theme="light"] .sec-title::after { color: #c9971a; -webkit-text-fill-color: #c9971a; text-shadow: none; }
@media (prefers-reduced-motion: no-preference) {
  .sec-title::after { animation: titleStar 6s linear infinite; }
}
@keyframes titleStar {
  0%   { transform: rotate(0deg) scale(1);     opacity: .95; }
  50%  { transform: rotate(180deg) scale(.78); opacity: .55; }
  100% { transform: rotate(360deg) scale(1);   opacity: .95; }
}

/* 데이터를 받는 동안 비어 있는 섹션 — 도는 별과 안내. 내용이 그려지면 :empty가 풀려 저절로 사라진다 */
.sec.active:empty { min-height: 50vh; align-items: center; justify-content: center; gap: 12px; }
.sec.active:empty::before {
  content: '✦'; font-size: 2rem; line-height: 1; color: rgb(var(--star));
  text-shadow: 0 0 14px rgba(var(--star),.7); animation: bootSpin 1.2s linear infinite;
}
.sec.active:empty::after { content: '불러오는 중'; font-size: .85rem; font-weight: 700; letter-spacing: 2px; color: var(--text-sub); }

@media (prefers-reduced-motion: reduce) {
  .sec.active, .overlay.open { animation: none; }
  .bhp-card:hover, .cg-card:hover { transform: none; }
  .boot__art, .boot__ring, .boot__spark, .boot__dots i, .sec.active:empty::before { animation: none; }
}

/* ── 홈 (home.js) ──
   뮤즈대시 첫 화면 구성: 머리 영역에 떠다니는 별·님·앱 스티커 글자와 소개 문구,
   그 아래 따로 선 내 캐릭터 칸, 가운데 카드가 앞으로 나오는 슬라이드. 움직임은 transform·opacity만 쓴다.
   모눈 무늬는 맨 뒷배경 body와 로딩 화면에만 쓴다 */
#sec-home { gap: 30px; }
/* 높이는 제목만큼만 잡는다. 남는 높이를 두고 가운데로 모으면 제목이 내려가서 윗변 기준으로 자리를 잡는 스티커와 어긋난다.
   테두리·배경·그림자 없이 맨 뒷배경 위에 제목과 스티커만 띄운다 */
.home-hero {
  position: relative; overflow: hidden; isolation: isolate;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 18px;
  padding: 44px 24px 16px; text-align: center;
}
.home-hero__spark { position: absolute; color: rgb(var(--star)); line-height: 1; text-shadow: 0 0 12px rgba(var(--star),.8); }
/* 머리 영역 좌우 메이플 아이콘 스티커 — 숨기지 않고, 화면이 좁아지면 좌우 %자리라 안쪽으로 모인다. 조금 겹치는 것은 괜찮다는 지수 의견.
   위아래 자리와 크기는 제목 글자 높이 --st-h에 맞춰 계산해서, 좁아져도 제목 옆 같은 높이에 머문다.
   --cy는 제목 윗변에서 스티커 가운데까지의 거리를 제목 높이 몇 배로 적은 것. 제목·캐릭터 칸이 스티커보다 위에 그려진다 */
.home-deco {
  --st-h: clamp(78px, 12vw, 124px);   /* 제목 .home-title과 같은 값 */
  --hero-pt: 44px;                     /* .home-hero 위쪽 여백, 곧 제목 윗변 */
  --ds: .62;                           /* 스티커 높이 = 제목 높이 × --ds. 한쪽에 넷이라 셋일 때보다 조금 작게 */
  position: absolute; inset: 0; pointer-events: none; z-index: 0;
}
.home-deco__s {
  position: absolute; width: auto; height: calc(var(--st-h) * var(--ds));
  top: calc(var(--hero-pt) + var(--st-h) * var(--cy) - var(--st-h) * var(--ds) / 2);
}
/* 한쪽에 넷. 위아래로 고르게 두고 안쪽·바깥쪽을 번갈아 지그재그로 */
.home-deco__s--1 { left: 5%;   --cy: .12;  rotate: -12deg; }
.home-deco__s--2 { left: 17%;  --cy: .7;   rotate: 9deg; }
.home-deco__s--3 { left: 5%;   --cy: 1.28; rotate: -6deg; }
.home-deco__s--4 { left: 17%;  --cy: 1.86; rotate: 7deg; }
.home-deco__s--5 { right: 16%; --cy: .12;  rotate: 14deg; }
.home-deco__s--6 { right: 4%;  --cy: .7;   rotate: -9deg; }
.home-deco__s--7 { right: 16%; --cy: 1.28; rotate: 8deg; }
.home-deco__s--8 { right: 4%;  --cy: 1.86; rotate: -7deg; }
.home-hero .home-title { position: relative; z-index: 1; margin-bottom: calc(var(--st-h) * .14); }
@media (max-width: 768px) { .home-deco { --hero-pt: 32px; } }
/* 폰은 자리가 좁아 크기를 줄인다 */
@media (max-width: 600px) {
  .home-deco { --ds: .46; }
}
.home-hero__spark--1 { top: 10%; right: 5%; font-size: 22px; }
.home-hero__spark--2 { top: 52%; left: 3%; font-size: 16px; color: #e4dcff; text-shadow: 0 0 12px rgba(214,200,255,.9); }
.home-hero__spark--3 { top: 12%; left: 24%; font-size: 12px; }
:root[data-theme="light"] .home-hero__spark--2 { color: #9b7be6; }
/* 로고 캐릭터 — 원본의 정확히 4배라 도트가 고르다. 가만히 있고, 올리면 웃는다 */
.home-hero__char { position: relative; width: 248px; height: 216px; }
.home-hero__face {
  position: absolute; inset: 0; width: 100%; height: 100%; image-rendering: pixelated;
  filter: drop-shadow(0 16px 18px rgba(0,0,0,.4)); transition: opacity .15s;
}
.home-hero__face--smile { opacity: 0; }
.home-hero__char:hover .home-hero__face--smile { opacity: 1; }
.home-hero__char:hover .home-hero__face:not(.home-hero__face--smile) { opacity: 0; }
/* 별·님·앱 스티커 글자 — 같은 글자를 노랑 바깥 테두리, 굵은 흰 테두리, 채움 순서로 겹친다.
   세 글자는 조금씩 기울이고 높낮이를 달리해 삐뚤빼뚤하게 놓고, 앱 오른쪽 아래에 글자와 조금 떨어뜨려
   큰 반짝이를, 그 오른쪽 아래에 아주 작은 반짝이를 둔다.
   채움 --st-g0 → g1 → g2는 0%·40%·100% 가로 그라데이션이고, g01·g12는 그 그라데이션의 1/3·2/3 지점 색이다.
   다크는 선명한 금색→라벤더, 라이트는 밝은 노랑→연보라로 칠한다.
   다크에서 옅은 파스텔로 채우면 흰 테두리에 묻혀 글자가 연해 보였다.
   색 변수는 아래 소개 문구 .home-tagline도 같이 쓴다 */
.home-title, .home-tagline {
  --st-ring: rgb(var(--star)); --st-white: #fff;
  --st-g0: rgb(var(--star)); --st-g1: #ffd257; --st-g2: var(--primary);
  --st-g01: color-mix(in srgb, var(--st-g0) 17%, var(--st-g1));
  --st-g12: color-mix(in srgb, var(--st-g1) 56%, var(--st-g2));
  --st-sa: #fff1b3; --st-sb: rgb(var(--star));
  --st-shadow: drop-shadow(0 5px 0 rgba(30,14,60,.45)) drop-shadow(0 12px 18px rgba(0,0,0,.35));
}
.home-title {
  --st-h: clamp(78px, 12vw, 124px);
  position: relative; display: flex; align-items: flex-end; justify-content: center;
  margin: 4px 0 calc(var(--st-h) * .44); line-height: 0;
}
:root[data-theme="light"] :is(.home-title, .home-tagline) {
  --st-ring: #ffbf1f; --st-white: #fff; --st-g0: #ffc83d; --st-g1: #ffe27a; --st-g2: #c4b5fd; --st-sa: #fff6c4; --st-sb: #ffc933;
  --st-shadow: drop-shadow(0 5px 0 rgba(150,110,20,.22)) drop-shadow(0 12px 16px rgba(150,110,20,.18));
}
.home-title__defs { position: absolute; width: 0; height: 0; overflow: hidden; }
.home-title__ch { display: block; flex: none; }
.home-title__ch svg { display: block; height: var(--st-h); width: auto; overflow: visible; filter: var(--st-shadow); }
:is(.home-title, .home-tagline) :is(text, path) {
  font-family: 'MapleTitle', 'Maple', sans-serif; font-size: 100px; font-weight: normal; font-synthesis: none;
  stroke-linejoin: round; stroke-linecap: round;
}
.home-title__ring  { fill: var(--st-ring);  stroke: var(--st-ring);  stroke-width: 28px; }
.home-title__white { fill: var(--st-white); stroke: var(--st-white); stroke-width: 20px; }
.home-title__ch--1 .home-title__fill { fill: url(#homeTitleFill1); }
.home-title__ch--2 .home-title__fill { fill: url(#homeTitleFill2); }
.home-title__ch--3 .home-title__fill { fill: url(#homeTitleFill3); }
.home-title__spark .home-title__fill { fill: url(#homeTitleSpark); }
/* 반짝이는 글자보다 작게 그려지므로 화면에서 글자와 같은 굵기로 보이게 테두리 값을 크기 비율만큼 키운다.
   글자 기준 흰 테두리는 글자 높이의 0.082배, 노랑 테두리 바깥 끝은 0.114배다 */
.home-title__spark .home-title__ring  { stroke-width: 51px; }
.home-title__spark .home-title__white { stroke-width: 36px; }
.home-title__ch--1 { rotate: -8deg; translate: 0 6px; }
.home-title__ch--2 { rotate: 5deg; translate: 0 -10px; margin-left: -4px; }
.home-title__ch--3 { rotate: -4deg; translate: 0 5px; margin-left: -4px; }
.home-title__spark { position: absolute; right: calc(var(--st-h) * -.7); bottom: calc(var(--st-h) * -.3); rotate: 10deg; }
.home-title__spark svg { height: calc(var(--st-h) * .72); }
/* 큰 반짝이 오른쪽 아래의 아주 작은 반짝이. 테두리 굵기는 글자·큰 반짝이와 같게 맞추고,
   두꺼운 테두리가 들어가도록 그림 칸을 -115~115로 넓혔다 */
.home-title__mini { right: calc(var(--st-h) * -.96); bottom: calc(var(--st-h) * -.56); rotate: -12deg; }
.home-title__mini svg { height: calc(var(--st-h) * .506); }
.home-title__mini .home-title__ring  { stroke-width: 104px; }
.home-title__mini .home-title__white { stroke-width: 74px; }
/* 별님앱 아래 두 줄 소개 문구 — 제목과 같은 스티커 글자를 두 줄 한 덩어리로 그린다. 움직이지 않는다. 자리 계산은 home.js _homeTaglineHtml.
   줄마다 세 낱말이 제목과 같은 금색→연보라 그라데이션을 나눠 이어 칠한다. 글자 크기는 제목의 0.4배이고,
   작은 글자에서 테두리가 가늘어 보이지 않게 제목보다 조금 굵게 준다. --st-h는 한 줄 높이, --tag-k는 그림 높이가 한 줄의 몇 배인지.
   반짝이들은 제목 오른쪽 끝 바깥에 있어 가운데 문구와 겹치지 않는다 */
.home-tagline {
  --st-h: clamp(31px, 4.8vw, 50px);
  --st-shadow: drop-shadow(0 3px 0 rgba(30,14,60,.45)) drop-shadow(0 6px 10px rgba(0,0,0,.3));
  position: relative; z-index: 1; display: flex; justify-content: center; line-height: 0;
}
:root[data-theme="light"] .home-tagline { --st-shadow: drop-shadow(0 3px 0 rgba(150,110,20,.22)) drop-shadow(0 6px 10px rgba(150,110,20,.16)); }
/* 같은 스티커 틀이라 제목 글자에 거는 둥실 움직임 .home-title__ch svg가 함께 걸리므로 끈다 */
.home-tagline .home-title__ch svg { height: calc(var(--st-h) * var(--tag-k)); animation: none; }
.home-tagline .home-title__ring  { stroke-width: 36px; }
.home-tagline .home-title__white { stroke-width: 26px; }
.home-tagline__f--1 { fill: url(#homeTitleFill1); }
.home-tagline__f--2 { fill: url(#homeTitleFill2); }
.home-tagline__f--3 { fill: url(#homeTitleFill3); }
/* 좁은 폰에서는 오른쪽 반짝이들이 머리 영역 밖으로 잘리므로 제목 묶음을 조금 왼쪽으로 옮긴다 */
@media (max-width: 480px) { .home-title { translate: calc(var(--st-h) * -.42) 0; } }

.home-block { display: flex; flex-direction: column; gap: 16px; }
.home-block[hidden] { display: none; }   /* char-home이 아니면 캐릭터 정보 칸을 통째로 숨긴다 */
.home-h {
  font-size: 1.35rem; font-weight: 900; letter-spacing: .5px;
  background: linear-gradient(90deg, #ffffff 0%, #f7e2ad 60%, #cac0f2 100%);
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}
.home-h::after { content: ' ✦'; color: rgb(var(--star)); -webkit-text-fill-color: rgb(var(--star)); font-size: .7em; }
:root[data-theme="light"] .home-h { background-image: linear-gradient(90deg, #241a35 0%, #5b3fb0 65%, #a8740a 100%); }
:root[data-theme="light"] .home-h::after { color: #c9971a; -webkit-text-fill-color: #c9971a; }

/* 내 캐릭터 — 머리 영역 밖, 바로 아래에 따로 선다. 사이드바에서 복사해 온 .sb-char-area를 홈 폭에 맞게 다시 배치한다.
   [캐릭터 + 추가 | 결정석 수입] / [명찰 | 결정석 막대] / [명찰 | 주간 수익 | 월간 수익] */
.home-mine { text-align: left; }
.home-mine .sb-char-area {
  display: grid; grid-template-columns: minmax(0, 420px) minmax(0, 1fr) minmax(0, 1fr); gap: 12px 16px; align-items: stretch;
  padding: 16px 18px 18px; border: 1px solid rgba(var(--hue),.22); border-radius: 12px;
  background: var(--panel-veil); box-shadow: 0 10px 30px rgba(0,0,0,.35);
}
:root[data-theme="light"] .home-mine .sb-char-area { background: #fff; box-shadow: 0 12px 30px rgba(150,110,20,.12); }
.home-mine .sb-char-head { grid-column: 1; padding: 0; }
/* 결정석·수익 칸 위 제목. 사이드바에서는 숨기고 홈에서만 캐릭터 제목과 같은 글자로 보인다 */
.sb-income-label { display: none; }
.home-mine .sb-income-label { display: block; grid-column: 2 / -1; grid-row: 1; align-self: center; max-width: none; }
.home-mine .char-list { grid-column: 1; grid-row: 2 / span 2; padding: 0; }
.home-mine .crystal-bar { grid-column: 2 / -1; grid-row: 2; align-self: center; padding: 4px 2px; }
.home-mine .sb-weekmeso { grid-row: 3; margin: 0; justify-content: center; padding: 14px 18px; }
.home-mine .sb-weekmeso:nth-child(5) { grid-column: 2; }
.home-mine .sb-weekmeso:nth-child(6) { grid-column: 3; }
.home-mine .sb-weekmeso__val { font-size: 1.3rem; }
/* 홈 결정석 줄의 일간·월간 결정석 그림은 사이드바보다 조금 크게. 너무 작다는 지수 의견, 사이드바는 그대로 */
.home-mine .crystal-bar__type { gap: 6px; font-size: .86rem; }
.home-mine .crystal-icon { width: auto; height: auto; }
/* 769~1099px — 메소 칸 둘을 옆으로 놓으면 칸이 좁아 금액이 서너 줄로 쪼개진다.
   [캐릭터 + 추가 | 결정석 수입] / [명찰 | 결정석 막대] / [명찰 | 주간 수익] / [명찰 | 월간 수익]으로 쌓는다 */
@media (min-width: 769px) and (max-width: 1099px) {
  .home-mine .sb-char-area { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .home-mine .char-list { grid-row: 2 / span 3; }
  .home-mine .sb-weekmeso { padding: 10px 16px; }
  .home-mine .sb-weekmeso:nth-child(5) { grid-column: 2; grid-row: 3; }
  .home-mine .sb-weekmeso:nth-child(6) { grid-column: 2; grid-row: 4; }
  .home-mine .sb-weekmeso__val { font-size: 1.15rem; }
}

/* 내 캐릭터 카드(app.js charHomeCardHtml) — 왼쪽 캐릭터 그림, 오른쪽 이름·직업·레벨·서버·경험치·랭킹·주간 수익 */
.char-card--home {
  border-radius: 10px; border-color: rgba(var(--star),.75); cursor: var(--cur-default);
  box-shadow: 0 0 0 1px rgba(var(--star),.3), 0 8px 22px rgba(0,0,0,.3);
}
.char-card--home:hover { border-color: rgb(var(--star)); }
/* 카드 위쪽 금빛 선 */
.char-card--home::before {
  content: ''; position: absolute; left: 0; right: 0; top: 0; height: 2px; z-index: 2;
  background: linear-gradient(90deg, transparent, rgb(var(--star)), rgba(var(--hue-l),.9), transparent);
}
/* 오른쪽 결정석·메소 칸이 카드보다 길어지면 카드가 그 높이까지 늘어나 위아래 끝을 맞춘다.
   늘어난 높이는 이름·레벨·경험치·랭킹 줄 사이에 고르게 나눠 준다 */
.home-mine .char-card--home { flex: 1; }
.hc { display: grid; grid-template-columns: 132px minmax(0, 1fr); height: 100%; }
.hc__pic {
  border-right: 1px solid rgba(var(--star),.22);
  background: radial-gradient(circle at 50% 60%, rgba(var(--hue),.45), transparent 70%);
}
.hc__body { display: flex; flex-direction: column; justify-content: space-between; gap: 7px; min-width: 0; padding: 12px 14px 10px; }
.hc__top { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; }
.hc__id { min-width: 0; }
.hc__name { font-size: 1.15rem; font-weight: 900; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hc__job { font-size: .76rem; font-weight: 700; color: var(--text-sub); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hc__jobicon { flex-shrink: 0; width: 52px; height: 52px; object-fit: contain; filter: drop-shadow(0 2px 4px rgba(0,0,0,.3)); }
.hc__meta { display: flex; align-items: center; gap: 8px; min-width: 0; }
.hc__lv { flex-shrink: 0; font-size: .86rem; font-weight: 900; color: var(--accent); }
.hc__server { display: flex; align-items: center; gap: 4px; min-width: 0; overflow: hidden; white-space: nowrap; font-size: .76rem; font-weight: 700; color: var(--text-sub); }
.hc__server img { flex-shrink: 0; width: 20px; height: 20px; object-fit: contain; }
.hc__exp { display: flex; align-items: center; gap: 8px; }
.hc__exp-lbl { font-size: .68rem; font-weight: 800; color: var(--text-sub); }
.hc__exp-track { position: relative; flex: 1; height: 8px; border-radius: 4px; overflow: hidden; background: rgba(var(--hue-l),.16); }
.hc__exp-track i { position: absolute; inset: 0 auto 0 0; border-radius: inherit; background: linear-gradient(90deg, rgb(var(--hue)), rgb(var(--star))); }
.hc__exp-val { font-size: .72rem; font-weight: 800; color: var(--accent); font-variant-numeric: tabular-nums; }
/* 랭킹·주간 수익 — 캐릭터 목록 카드처럼 왼쪽 이름, 오른쪽 값을 한 줄씩. 줄 사이에 가는 선 */
.hc__stats { display: flex; flex-direction: column; border-top: 1px solid var(--border); }
.hc__stat { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-width: 0; padding: 5px 0; border-bottom: 1px solid var(--border); }
.hc__stat:last-child { border-bottom: none; padding-bottom: 0; }
.hc__stat span { min-width: 0; font-size: .76rem; font-weight: 600; color: var(--text-sub); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hc__stat b { flex-shrink: 0; font-size: .92rem; font-weight: 900; color: var(--text); font-variant-numeric: tabular-nums; white-space: nowrap; }
.char-weekly.is-neg { color: var(--danger); }

:root[data-theme="light"] .hc__pic { background: radial-gradient(circle at 50% 60%, rgba(var(--star),.35), transparent 70%); }

/* 추천 기능 슬라이드 — 가운데 카드는 앞으로, 양옆은 작고 흐리게 뒤로(뮤즈대시 카드 슬라이드) */
.home-car { position: relative; height: 344px; overflow: hidden; touch-action: pan-y; border-radius: 12px; }
/* 위아래 22px은 카드 그림자 자리 — 바깥은 잘라서 양옆 카드가 사이드바 위로 넘어가지 않게 한다 */
.home-car__track { position: absolute; inset: 22px 0; }
.home-slide {
  position: absolute; top: 0; left: 50%; width: min(580px, 78%); height: 100%;
  display: grid; grid-template-columns: 44% 1fr; text-align: left;
  border-radius: 12px; overflow: hidden; cursor: var(--cur-pointer);
  background: var(--bg2); border: 1px solid rgba(var(--hue-l),.32);
  box-shadow: 0 18px 44px rgba(0,0,0,.45);
  transform: translateX(-50%) scale(.76); opacity: 0; pointer-events: none;
  transition: transform .55s cubic-bezier(.2,.8,.2,1), opacity .55s;
}
.home-slide.is-cur  { transform: translateX(-50%) scale(1); opacity: 1; z-index: 3; pointer-events: auto; }
.home-slide.is-prev { transform: translateX(-118%) scale(.82); opacity: .4; z-index: 2; pointer-events: auto; }
.home-slide.is-next { transform: translateX(18%) scale(.82); opacity: .4; z-index: 2; pointer-events: auto; }
.home-slide.is-cur:hover { box-shadow: 0 22px 50px rgba(0,0,0,.5), 0 0 0 1px rgba(var(--star),.45); }
:root[data-theme="light"] .home-slide { background: #fff; box-shadow: 0 16px 40px rgba(150,110,20,.16); }
.home-slide__pic {
  position: relative; display: grid; place-items: center; overflow: hidden;
  background:
    radial-gradient(circle at 50% 45%, rgba(var(--hue),.5), transparent 70%),
    linear-gradient(160deg, #24173f, #120b22);
}
:root[data-theme="light"] .home-slide__pic {
  background:
    radial-gradient(circle at 50% 45%, rgba(var(--star),.35), transparent 70%),
    linear-gradient(160deg, #fff6dc, #efe6ff);
}
.home-slide__icon { position: relative; width: 96px; height: 96px; object-fit: contain; image-rendering: pixelated; filter: drop-shadow(0 10px 14px rgba(0,0,0,.35)); }
/* 아이콘 뒤에서 도는 금빛 고리 */
.home-slide__glow {
  position: absolute; width: 150px; height: 150px; border-radius: 50%;
  background: conic-gradient(from 0deg, transparent 0 60%, rgba(var(--star),.9) 80%, rgba(var(--hue-l),.85) 92%, transparent);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 2px));
          mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 2px));
}
.home-slide__body { display: flex; flex-direction: column; justify-content: center; gap: 8px; padding: 26px 24px; }
.home-slide__title { font-size: 1.35rem; font-weight: 900; color: var(--text); }
.home-slide__desc { font-size: .9rem; font-weight: 600; line-height: 1.5; color: var(--text-sub); }
.home-slide__go {
  align-self: flex-start; margin-top: 10px; padding: 7px 16px; border-radius: var(--radius);
  font-size: .8rem; font-weight: 800; color: var(--accent);
  background: rgba(var(--star),.14); border: 1px solid rgba(var(--star),.45);
}
:root[data-theme="light"] .home-slide__go { color: #8a6200; background: rgba(214,160,20,.12); }
.home-car__nav {
  position: absolute; top: 50%; z-index: 4; width: 42px; height: 42px; margin-top: -21px; border-radius: var(--radius-lg);
  font-size: 1.7rem; line-height: 1; color: #fff;
  background: rgba(10,6,22,.55); border: 1px solid rgba(255,255,255,.2);
  transition: background .2s, transform .2s;
}
.home-car__nav:hover { background: rgba(var(--star),.85); color: #2a1a00; transform: scale(1.08); }
.home-car__nav--prev { left: 6px; }
.home-car__nav--next { right: 6px; }
.home-car__dots { display: flex; justify-content: center; gap: 8px; }
.home-car__dot { width: 8px; height: 8px; border-radius: var(--radius-pill); background: rgba(var(--hue-l),.35); transition: width .3s, background .3s; }
.home-car__dot.active { width: 26px; background: rgb(var(--star)); }

/* 전체 기능 바둑판 */
/* 카드 묶음은 모든 줄을 가장 높은 줄에 맞춘다. 이름이 두 줄로 내려가도 카드 높이는 그대로다 */
.home-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); grid-auto-rows: 1fr; gap: 12px; }
.home-tile {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  padding: 18px 10px 16px; border-radius: 10px;
  background: var(--panel-veil); border: 1px solid rgba(var(--hue),.22);
  transition: transform .22s cubic-bezier(.2,.8,.2,1), border-color .2s, box-shadow .2s;
}
.home-tile:hover { transform: translateY(-4px); border-color: rgba(var(--star),.55); box-shadow: 0 12px 26px rgba(0,0,0,.4), 0 0 0 1px rgba(var(--star),.2); }
:root[data-theme="light"] .home-tile { background: #fff; }
:root[data-theme="light"] .home-tile:hover { box-shadow: 0 12px 26px rgba(150,110,20,.15); }
.home-tile__icon { display: grid; place-items: center; width: 58px; height: 58px; border-radius: 10px; background: radial-gradient(circle, rgba(var(--hue),.38), transparent 70%); }
.home-tile__icon img { max-width: 44px; max-height: 44px; transition: transform .25s cubic-bezier(.3,1.6,.5,1); }
.home-tile:hover .home-tile__icon img { transform: scale(1.18) rotate(-6deg); }
.home-tile__name { font-size: .82rem; font-weight: 800; text-align: center; color: var(--text); }

@media (max-width: 768px) {
  .home-hero { padding: 32px 12px 16px; }
  .home-hero__char { width: 186px; height: 162px; }   /* 원본의 3배 */
  .home-car { height: 424px; }
  .home-mine .sb-char-area { grid-template-columns: minmax(0, 1fr); }
  .home-mine :is(.char-list, .sb-income-label, .crystal-bar, .sb-weekmeso:nth-child(5), .sb-weekmeso:nth-child(6)) { grid-column: 1; grid-row: auto; }
  .hc { grid-template-columns: 104px minmax(0, 1fr); }
  .hc__stat b { font-size: .86rem; }
  .home-slide { width: 84%; grid-template-columns: 1fr; grid-template-rows: 170px 1fr; }
  .home-slide.is-prev { transform: translateX(-128%) scale(.82); }
  .home-slide.is-next { transform: translateX(28%) scale(.82); }
  .home-slide__body { padding: 16px 18px 20px; }
  .home-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
}

@media (prefers-reduced-motion: no-preference) {
  .home-hero__spark { animation: bootTwinkle 2.2s ease-in-out infinite; }
  .home-hero__spark--2 { animation-delay: .7s; }
  .home-hero__spark--3 { animation-delay: 1.4s; }
  /* 글자마다 박자를 어긋나게 해서 따로따로 떠다닌다 */
  .home-title__ch svg { animation: stickerFloat 2.2s cubic-bezier(.45,.05,.55,.95) infinite alternate; }
  .home-title__ch--2 svg { animation-duration: 2.5s; animation-delay: -.8s; }
  .home-title__ch--3 svg { animation-duration: 2.3s; animation-delay: -1.5s; }
  .home-title__spark svg { animation: sparkFloat 1.9s cubic-bezier(.45,.05,.55,.95) infinite alternate; animation-delay: -.4s; }
  .home-title__mini svg { animation-duration: 1.5s; animation-delay: -1.1s; }
  /* 스티커마다 박자를 달리해 천천히 둥실 */
  .home-deco__s { animation: decoFloat 3.2s cubic-bezier(.45,.05,.55,.95) infinite alternate; }
  .home-deco__s--2 { animation-duration: 2.7s; animation-delay: -1.1s; }
  .home-deco__s--3 { animation-duration: 3.6s; animation-delay: -2.2s; }
  .home-deco__s--4 { animation-duration: 2.9s; animation-delay: -.6s; }
  .home-deco__s--5 { animation-duration: 3.4s; animation-delay: -1.7s; }
  .home-deco__s--6 { animation-duration: 3s;   animation-delay: -2.6s; }
  .home-deco__s--7 { animation-duration: 3.3s; animation-delay: -.9s; }
  .home-deco__s--8 { animation-duration: 2.8s; animation-delay: -2s; }
  .home-slide__glow { animation: bootSpin 6s linear infinite; }
  .home-slide__icon { animation: heroIconFloat 2.6s ease-in-out infinite alternate; }
  .sec--enter .home-block { animation: riseIn .6s cubic-bezier(.2,.8,.2,1) backwards; animation-delay: .16s; }
  .sec--enter .home-block--mine { animation-delay: .08s; }
}
@keyframes stickerFloat { from { transform: translateY(3px); } to { transform: translateY(-9px); } }
@keyframes sparkFloat { from { transform: translateY(2px) rotate(-8deg); } to { transform: translateY(-11px) rotate(8deg); } }
@keyframes decoFloat { from { transform: translateY(4px) rotate(-3deg); } to { transform: translateY(-10px) rotate(3deg); } }
@keyframes heroIconFloat { from { transform: translateY(4px); } to { transform: translateY(-6px); } }

/* ── 햄버거 / 드로어 오버레이 (기본: 데스크탑에선 숨김) ── */
#sbBtnSettings { display: none; }
.hamburger { display: none; flex-direction: column; justify-content: center; gap: 4px; width: 34px; height: 34px; padding: 6px; border-radius: 8px; flex-shrink: 0; }
.hamburger span { display: block; height: 2px; width: 100%; background: var(--primary); border-radius: 2px; transition: .25s; }
body.sidebar-open .hamburger span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
body.sidebar-open .hamburger span:nth-child(2) { opacity: 0; }
body.sidebar-open .hamburger span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }
.sidebar-overlay { display: none; }


/* ══════════════ 데스크톱 사이드바(340px) + 고정폭 320px 우측 패널 조합에서
   768px보다 넓은 폭(769~~890px대)에서도 좌측 칼럼이 40px대로 짜부라지는
   구간이 있어 minmax(0,1fr)만으로는 부족 — 이 폭에서는 아예 1열로 전환 ══════════════ */
@media (max-width: 920px) {
  .gen-main-layout { grid-template-columns: 1fr; }
  .sf-layout { grid-template-columns: 1fr !important; }
}

/* ══════════════ 모바일 레이아웃 (≤768px) ══════════════ */
@media (max-width: 768px) {
  .hamburger { display: flex; }
  #sbBtnSettings { display: inline-flex; font-size: .76rem; padding: 5px 13px; }
  #headerBtnSettings { display: none; }
  .header { padding: var(--safe-top) 14px 0; gap: 10px; }
  /* 로고는 폭이 모자라면 줄어들되 말줄임으로 처리 — 우측 초기화/타이머를 밀어내지 않게 */
  .header__logo { min-width: 0; overflow: hidden; }
  /* ★ 예전엔 .header__title 자체(줄 두 개를 담는 flex column)에 nowrap+ellipsis를
     걸었다. 그건 "가로로 한 줄"에만 뜻이 있는 속성이라 세로로 쌓인 줄에는 안 먹혀서
     결국 영문 줄을 통째로 숨기는 걸로 때웠었다. 이제 한글/영문 줄을 각각 감싸서
     그 줄 안에서만 말줄임되게 한다 — 폭이 모자라도 그 줄만 "메이뿌…"처럼 줄고
     둘째 줄은 그대로 남는다. */
  .header__title { font-size: .8rem; min-width: 0; }
  .header__title-kr, .header__title-en { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .header__center { gap: 6px; flex-shrink: 0; }
  /* nowrap이 없으면 "초기화"/타이머가 글자 단위로 세로로 쪼개진다 */
  /* 테마 토글은 헤더 폭을 먹어 로고가 "Byeolni..."로 잘리게 만든다.
     모바일에서는 숨기고 설정 모달의 "화면 테마"에서 고르게 한다. */
  .theme-toggle-wrap { display: none; }
  .theme-toggle__label { display: none; }
  .header__right .hbtn { padding: 6px 10px; font-size: .72rem; }

  /* 터치 영역 확보 — 라벨로 감싸이지 않아 아이콘 자체를 정확히 눌러야 하는 버튼들.
     보기 크기(글꼴·배경)는 그대로 두고 최소 눌림 영역만 넓힌다. */
  .modal__close { width: 40px; height: 40px; font-size: 1.15rem; }
  .ccbtn { min-height: 34px; padding-left: 12px; padding-right: 12px; }
  .cube-set__del { min-width: 34px; min-height: 34px; padding: 8px; }
  .pm, .pp { min-width: 36px; min-height: 36px; }
  .cg-card__save { min-height: 34px; }

  /* 달력 날짜 칸 키우기 — 375px에서 칸이 40px밖에 안 나와 누르기 힘들었다.
     칸은 정사각형(aspect-ratio)이라 세로만 늘릴 수 없고, min-height를 주면
     폭보다 커져서 칸끼리 겹친다. 결국 좌우 여백에서 폭을 회수하는 수밖에 없어
     패널 여백(18→8)·칸 간격(5→4)을 줄이고 패널을 좌우로 4px씩 내밀어
     40 → 약 45px을 확보한다. */
  .mc-panel { padding: 14px 8px; margin-left: -4px; margin-right: -4px; }
  .mc-grid { gap: 4px; }
  .mc-cell { padding: 4px; }

  /* 압축 모드 전환은 화면 폭이 아니라 칸 크기 기준이라 .mc-grid--compact로 뺐다 */

  /* 그리드 해제 → 콘텐츠 전체폭 */
  .app { display: block; min-width: 0; }
  /* 홈 화면 실행 시 맨 아래 내용이 홈 인디케이터에 가리지 않게 그만큼 더 띄운다 */
  .content { padding: 14px; padding-bottom: calc(14px + var(--safe-bottom)); min-height: 0; }

  /* 사이드바 = 좌측 슬라이드 드로어 */
  .sidebar {
    position: fixed; top: var(--top-h); left: 0; z-index: 90;
    width: 80vw; max-width: 300px; height: calc(100vh - var(--top-h));
    transform: translateX(-100%);
    transition: transform .28s ease;
    overflow-y: auto; -webkit-overflow-scrolling: touch;
  }
  /* 80vw가 300px보다 좁아지는 소형 화면(~<375px)에서는 일러스트를 줄여
     "Arch Mage (Ice, Lightning)" 같은 긴 직업명도 한 줄에 들어가게 한다 */
  .char-card__inner { grid-template-columns: minmax(0, 1fr) 100px; }
  body.sidebar-open .sidebar { transform: translateX(0); }

  /* 드로어 배경 오버레이 */
  .sidebar-overlay {
    display: block; position: fixed; inset: 60px 0 0 0; z-index: 80;
    background: rgba(0,0,0,.55); opacity: 0; pointer-events: none;
    transition: opacity .28s ease;
  }
  body.sidebar-open .sidebar-overlay { opacity: 1; pointer-events: auto; }

  /* 캐릭터 그리드 5열 → 2열 */
  /* 모바일은 1열 — 아래로 쌓인다 */
  .cg-grid { grid-template-columns: minmax(0, 1fr); gap: 10px; }

  /* 보스 테이블 → 카드형 */
  .boss-table-wrap { overflow-x: visible; }
  .boss-table { min-width: 0; display: block; }
  .boss-table thead { display: none; }
  .boss-table tbody { display: flex; flex-direction: column; gap: 6px; }
  .boss-table tr {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: auto auto;
    gap: 4px 8px;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--bg2);
  }
  /* 데스크톱의 `tbody tr`(윗선만)·`:first-child`(윗선 없음) 규칙이 더 구체적이라
     카드 테두리가 한쪽만 남거나 첫 카드만 윗선이 빠진다 — 같은 구체성으로 덮는다 */
  .boss-table tbody tr,
  .boss-table tbody tr:first-child { border: 1px solid var(--border); }
  .boss-table tbody tr.done { border-color: rgba(var(--hue),.4); }
  .boss-table tr.locked { opacity: .45; }
  .boss-table td { display: block; padding: 0; border: none; }
  .boss-table td:nth-child(1) { grid-column: 1 / -1; }
  .boss-table td:nth-child(2) { grid-column: 1 / -1; }
  .boss-table td:nth-child(3) { grid-column: 1; display: flex; align-items: center; }
  .boss-table td:nth-child(4) { grid-column: 2; display: flex; align-items: center; justify-content: flex-end; }
  .rev-val { font-size: .85rem; }
  .rev-dash { color: var(--text-sub); }

  /* 제네시스/데스티니 2열 → 1열 */
  .gen-main-layout { grid-template-columns: 1fr; }
  .gen-stat-panel.card { position: static; }
  .gen-input-row { flex-direction: column; }
  .gen-input-row .field { flex: none; width: 100%; }
  .gen-cfg-card { width: 100%; }

  /* HEXA 2열 → 1열 */
  .hexa-layout { grid-template-columns: 1fr; }

  /* 큐브 결과 모달: 좌우 분할 → 세로 스택 */
  .cube-result-left { flex: none; width: 100%; min-width: 0; }
  .cube-result-right { overflow-y: visible; border: none; padding: 0; }
  .modal--cube-result { width: calc(100vw - 32px); max-height: 88dvh; }
  .modal--cube-result .modal__body { overflow-y: auto !important; padding: 20px !important; flex: 1; max-height: none; }
  .cube-result-body { flex-direction: column; overflow: visible; padding: 16px; overflow-y: auto; max-height: calc(88dvh - 56px); }
  .sf-res-item { gap: 8px; }
  .sf-res-val { font-size: .82rem; text-align: right; min-width: 0; word-break: break-all; }
  .sf-res-val.big { font-size: .95rem; }

  /* 추옵·스타포스·큐브·환산 좌우 → 세로 (2~5) */
  .sf-layout { grid-template-columns: 1fr !important; }

  /* 보스HP 카드: 5열 → 2열, 글자 자동 축소 (6) */
  .bhp-grid { grid-template-columns: repeat(2, 1fr); gap: 8px; }
  .bhp-card__name { font-size: .82rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .bhp-active-diff .dpill { font-size: clamp(.55rem, 3.5vw, 1.3rem); padding: 4px 2px; }
  .bhp-phase { font-size: .75rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .bhp-phase__val { font-size: .82rem; white-space: nowrap; }

  /* 추옵 시뮬레이터 상단 탭: 좁은 화면에서 2줄로 꺾이며 헤더와 겹치는 문제 (2) */
  .sf-tabs { width: 100%; }
  .sf-tab { flex: 1; padding: 10px 4px; font-size: .78rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

  /* 스타포스 단계별 확률: 라벨+숫자가 세로로 쪼개지는 문제 (2) */
  .sf-stage-info { flex-direction: column; align-items: flex-end; gap: 1px; font-size: .68rem; }
  .sf-stage-prob--succ, .sf-stage-prob--fail, .sf-stage-prob--dest { white-space: nowrap; }
  .sf-my-result { flex-wrap: wrap; }
  .sf-my-result__tag, .sf-my-result__meso { white-space: nowrap; }

  /* 서버 상태: 긴 월드명(Challengers-Heroic 등)이 꺾이는 문제 (4) */
  .icon-lbl { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; display: inline-block; }

  /* 보스 패널 헤더: 캐릭터명 + 결정석 + 초기화 줄바꿈 방지 */
  .boss-panel__head { flex-wrap: wrap; gap: 6px; padding: 10px 14px; }
  .boss-panel__charname { font-size: .82rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 120px; }
  .boss-crystal-count .cc-item { font-size: .88rem; }

  /* 헥사 노드: 이름 1줄 + 현재/목표 같은 줄 */
  .hexa-support-item { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
  .hx-node-name { width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .hexa-support-item span:not(.hx-node-name) { font-size: .72rem; }
  .hexa-support-item .inp { width: 60px; min-width: 0; }

  /* form 라벨 줄바꿈 방지 (스타포스 등) */
  .field__label { font-size: .78rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
}

/* 아주 좁은 화면: 캐릭터 그리드 1열 */
@media (max-width: 420px) {
  .cg-grid { gap: 8px; }
}

/* ═══ 추옵 시뮬레이터 ═══ */
/* table-layout:fixed → 값 유무와 관계없이 열 너비 고정 (빈 칸이어도 안 좁아짐) */
.flame-tbl { width: 100%; border-collapse: collapse; font-size: .82rem; table-layout: fixed; }
.flame-tbl th { padding: 6px 10px; background: var(--bg3); color: var(--text-sub); font-weight: 600; text-align: center; border-bottom: 1px solid var(--border); white-space: nowrap; }
.flame-tbl td { padding: 5px 10px; text-align: center; border-bottom: 1px solid rgba(255,255,255,.05); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* 첫 열(스탯명) 고정폭, 나머지 5개 등급열은 남은 폭 균등 분배 */
.flame-tbl th:first-child, .flame-tbl .flame-opt-lbl { width: 30%; }
.flame-tbl .flame-opt-lbl { text-align: left; color: var(--text); font-weight: 500; }
.flame-t--zero { color: var(--text-sub); opacity: .35; }
.flame-score-card { padding: 12px 0; border-bottom: 1px solid var(--border); }
.flame-score-card:last-of-type { border-bottom: none; }
.flame-score-card__name { font-weight: 700; font-size: .95rem; margin-bottom: 4px; }
.flame-score-card__prob { font-size: .82rem; color: var(--text-sub); }
.flame-score-card__mean { font-size: .82rem; color: var(--text-sub); margin-bottom: 2px; }
.flame-th-prob { font-size: .72rem; font-weight: 400; color: var(--text-sub); }
/* 원본 픽셀 크기 그대로, 100px 상자보다 큰 것만 줄인다(사이드바 아이콘과 동일한 원칙) */
.flame-type-icon { width: auto; height: auto; max-width: 100px; max-height: 100px; object-fit: contain; display: block; margin: 0 auto 4px; }

tbody tr:hover { background: rgba(var(--hue),.05); }

/* ── 설정 모달 ── */
.modal--settings { width: min(880px, 96vw); }
.settings-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
  padding: 20px;
}
.settings-box {
  background: var(--bg3);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.settings-box__title {
  font-size: .88rem;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 2px;
}
.settings-box__desc {
  font-size: .78rem;
  color: var(--text-sub);
  line-height: 1.5;
  flex: 1;
}
.settings-box__warn {
  font-size: .74rem;
  color: var(--danger);
  line-height: 1.5;
}
.settings-font-btns {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* ── 클라우드 저장(로그인) — 헤더 로그인 버튼이 여는 모달 안에 들어간다 */
.cs-row { display: flex; gap: 8px; }
.cs-row .sbtn { flex: 1; }
/* min-width:0 이 없으면 input의 기본 최소폭 때문에 좁은 칸에서 넘친다 */
.cs-inp { flex: 1; min-width: 0; }
.cs-me {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 8px 12px;
  background: var(--bg2); border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.cs-me__body { display: flex; align-items: baseline; gap: 6px; min-width: 0; }
.cs-me__nick { font-size: .92rem; font-weight: 800; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cs-me__idsub { font-size: .74rem; color: var(--text-dim); flex-shrink: 0; }
.cs-tabs { display: flex; gap: 6px; }
.cs-tab {
  flex: 1; padding: 8px 0; border-radius: var(--radius-sm);
  font-size: .84rem; font-weight: 800; color: var(--text-sub);
  background: var(--bg3); border: 1px solid var(--border);
}
.cs-tab.sel { color: var(--on-btn); background: var(--btn); border-color: transparent; }
.cs-pwbox {
  padding: 12px; background: var(--bg3); border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

@media (max-width: 768px) {
  .settings-grid { grid-template-columns: 1fr; }
}

/* ── 관리자 발송 모달 ──
   기본 모달은 max-height:70vh 라 아래 버튼이 스크롤에 가려 안 보였다.
   항목이 적으므로 여유를 주고 간격을 좁혀 한 화면에 들어오게 한다. */
#overlayAdmin .modal__body { max-height: 86vh; gap: 10px; }

/* ── 관리자 발송 결과 줄 ── */
.adm-result { margin-top: 10px; font-size: .82rem; font-weight: 700; min-height: 1.2em; color: var(--text-sub); }
.adm-result.is-ok  { color: var(--success); }
.adm-result.is-err { color: var(--danger); }

/* ── 숙제 트래커 ── */
/* 두 개씩 놓되 카드 한 칸이 340px보다 좁아지면 한 줄에 하나씩. 지수가 캡처로 정한 기준: 한 칸 약 350px까지는 두 개씩이 괜찮고
   그보다 좁은 두 칸은 보기 불편하다. 칸 최소 폭을 340px과 절반 폭 중 큰 값으로 잡아 세 칸 이상은 생기지 않는다 */
.dt-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, max(340px, calc((100% - 14px) / 2))), 1fr)); gap: 14px; align-items: stretch; }
.dt-card { display: flex; flex-direction: column; gap: 12px; transition: opacity .15s, border-color .15s; container-type: inline-size; }
.dt-card__head { display: flex; align-items: center; gap: 12px; }
/* 캘린더 칩·프론티어 덱과 같은 112px. cover는 96px 아바타의 가장자리를 잘라내므로
   contain으로 전체가 들어오게 한다(다른 화면과 같은 처리). */
.dt-card__portrait {
  flex: none; width: 112px; height: 112px; border-radius: var(--radius-sm); overflow: hidden;
  display: flex; align-items: center; justify-content: center; background: transparent;
}
.dt-card__portrait-img { max-width: 100%; max-height: 100%; object-fit: contain; image-rendering: pixelated; }
.dt-card__whoBody { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.dt-card__name { min-width: 0; font-weight: 800; font-size: 1.2rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dt-card__lv { font-size: .86rem; font-weight: 900; color: var(--accent); }
/* 직업 이름·레벨·서버·직업 일러스트 — 캐릭터 목록 카드와 같은 정보와 같은 금색 테두리 */
/* 카드가 좁으면 직업 이름과 서버가 잘리지 않고 다음 줄로 내려간다 */
.dt-card__job { min-width: 0; font-size: .82rem; font-weight: 700; color: var(--text-sub); }
.dt-card__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 8px; min-width: 0; margin-top: 2px; }
.dt-card__server { display: flex; align-items: center; gap: 4px; min-width: 0; overflow: hidden; white-space: nowrap; font-size: .8rem; font-weight: 700; color: var(--text-sub); }
.dt-card__server img { flex-shrink: 0; width: 20px; height: 20px; object-fit: contain; }
.dt-card__jobicon { flex: none; align-self: flex-start; width: 52px; height: 52px; object-fit: contain; border-radius: 9px; border: 1px solid rgba(184,134,11,.6); background: rgba(184,134,11,.13); }
/* 위 기본 크기보다 뒤에 둬야 덮인다. 카드가 좁으면 캐릭터 그림 칸을 원본 96px로, 직업 일러스트를 36px로 줄여 이름·직업·서버 칸을 넓힌다 */
@container (max-width: 380px) {
  .dt-card__portrait { width: 96px; height: 96px; }
  .dt-card__jobicon { width: 36px; height: 36px; }
  .dt-card__head { gap: 8px; }
}
.dt-card__edit {
  flex: none; width: 22px; height: 22px; border-radius: 50%; border: none; background: transparent;
  color: var(--text-dim); font-size: .92rem; line-height: 1; cursor: var(--cur-pointer); transition: background .15s, color .15s;
}
.dt-card__edit:hover { background: rgba(var(--hue),.18); color: var(--primary); }
.dt-help { font-size: .78rem; color: var(--text-sub); margin: 6px 0 14px; word-break: keep-all; }
.dt-step2-head { display: flex; align-items: center; gap: 14px; margin-bottom: 16px; }
.dt-step2-portrait { flex: none; width: 112px; height: 112px; border-radius: var(--radius-sm); object-fit: contain; image-rendering: pixelated; background: rgba(0,0,0,.2); }
.dt-step2-namebox { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.dt-step2-name { font-size: 1.35rem; font-weight: 800; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dt-step2-lv { font-size: .82rem; font-weight: 700; color: var(--text-dim); }
#dtEditWho { flex: none; }
.dt-addform__presets { display: flex; flex-wrap: wrap; gap: 6px; }
.dt-addform__opt {
  display: flex; align-items: center; gap: 5px; padding: 5px 10px; border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: rgba(0,0,0,.1); font-size: .78rem; font-weight: 700;
  color: var(--text-dim); cursor: var(--cur-pointer); transition: background .15s, border-color .15s, color .15s;
}
.dt-addform__opt input { display: none; }
.dt-addform__opt--checked { background: rgba(var(--hue),.15); border-color: rgba(var(--hue),.4); color: var(--text); }
/* 같은 월드에서 이미 제한 수만큼 켠 별조각 상자·몬스터 파크 */
.dt-addform__opt--off { opacity: .4; cursor: not-allowed; }
/* 항목 2개씩 고정 폭으로 줄바꿈 — 이름 길이와 무관하게 상자 크기가 통일되고,
   최대 5개(3줄)만큼 높이를 항상 확보해서 항목 개수와 무관하게 카드 크기가 같아진다 */
.dt-tiles {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-rows: 46px;
  gap: 8px; min-height: calc(46px * 3 + 8px * 2);
}
.dt-tile {
  position: relative; display: flex; align-items: center; gap: 8px; min-width: 0;
  padding: 7px 12px 7px 7px; border-radius: var(--radius-sm); cursor: var(--cur-pointer); overflow: hidden;
  border: 1px solid var(--border); transition: background .15s, border-color .15s, opacity .15s;
}
/* 아이콘 원본이 33x30 ~ 39x39로 제각각이다. 예전에는 30px 칸에 width/height 100%로
   욱여넣어 전부 억지로 늘리고 줄이느라 뭉개졌다. 칸을 제일 큰 것에 맞추고 각 그림은
   원본 크기 그대로 가운데 두면 확대·축소가 없어 선명하다. */
.dt-tile__thumb {
  flex: none; width: 39px; height: 39px; border-radius: var(--radius-sm); overflow: hidden;
  display: flex; align-items: center; justify-content: center; background: transparent;
}
.dt-tile__img {
  width: auto; height: auto; max-width: 100%; max-height: 100%;
  filter: grayscale(1) brightness(.55); transition: filter .15s;
}
.dt-tile__emoji { font-size: 1.15rem; line-height: 1; filter: grayscale(1); opacity: .4; transition: filter .15s, opacity .15s; }
.dt-tile__label { flex: 1 1 auto; min-width: 0; font-size: .82rem; font-weight: 700; color: var(--text-dim); transition: color .15s; }
.dt-tile--active { background: rgba(var(--hue),.1); border-color: rgba(var(--hue),.35); }
.dt-tile--active:hover { background: rgba(var(--hue),.16); }
.dt-tile--active .dt-tile__img { filter: none; }
.dt-tile--active .dt-tile__emoji { filter: none; opacity: 1; }
.dt-tile--active .dt-tile__label { color: var(--text); }
.dt-tile--done { background: rgba(74,222,128,.1); border-color: rgba(74,222,128,.4); }
/* 카드 안에서 직접 항목을 고르는 칸. 처음에는 항목 없이 이 칸만 있다 */
.dt-tile--add { justify-content: center; border-style: dashed; background: transparent; color: var(--text-sub); font: inherit; font-size: .82rem; font-weight: 700; }
.dt-tile--add:hover { color: var(--text); background: rgba(var(--hue),.08); }
.dt-tile--done .dt-tile__img { opacity: .4; }
.dt-tile--done .dt-tile__emoji { opacity: .35; }
.dt-tile__stamp {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%) rotate(-12deg);
  font-size: .68rem; font-weight: 900; letter-spacing: .06em; color: var(--success);
  border: 2px solid var(--success); border-radius: 4px; padding: 1px 6px; text-transform: uppercase;
  animation: dtStampIn .18s ease-out; pointer-events: none;
}
@keyframes dtStampIn { from { transform: translate(-50%,-50%) rotate(-12deg) scale(1.6); opacity: 0; } to { transform: translate(-50%,-50%) rotate(-12deg) scale(1); opacity: 1; } }

@media (max-width: 768px) {
  .dt-grid { grid-template-columns: 1fr !important; }
  .dt-tiles { grid-template-columns: 1fr !important; min-height: 0 !important; }
}

/* ── 오늘의 채널 추천 ── */
.wc-category { margin-bottom: 22px; }
.wc-category__title {
  font-size: 1.12rem; font-weight: 900; color: var(--primary); margin-bottom: 11px;
  border-left: 4px solid var(--primary); padding-left: 10px; line-height: 1.3;
}
.wc-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.wc-item {
  display: flex; align-items: center; gap: 10px; padding: 8px 12px; min-width: 0;
  border-radius: var(--radius-sm); border: 1px solid var(--border); background: var(--bg-card);
  cursor: var(--cur-pointer); transition: background .15s, border-color .15s;
}
.wc-item:hover { background: var(--bg-hover); }
/* 아이콘을 고정폭 상자(사이드바 nav와 동일한 패턴)에 넣어서, 그림 크기가
   제각각이어도 옆 텍스트는 항상 같은 위치에서 시작하게 한다. */
/* 아이템 아이콘은 게임 원본 크기 그대로. 가장 큰 38×38, 35×39가 들어가는 40px 칸 */
.wc-item__img-wrap { width: 40px; height: 40px; flex: none; display: inline-flex; align-items: center; justify-content: center; }
.wc-item__img { width: auto; height: auto; }
.wc-item__name { flex: 1 1 auto; min-width: 0; font-size: .8rem; font-weight: 700; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wc-result { display: flex; align-items: center; gap: 14px; }
.wc-result__img { flex: none; width: 84px; height: 84px; object-fit: contain; }
.wc-result__item { font-size: .8rem; color: var(--text-sub); font-weight: 700; }
.wc-result__pick { font-size: 1.2rem; font-weight: 900; color: var(--accent); margin: 2px 0; display: flex; align-items: center; gap: 7px; min-width: 0; }
.wc-result__world { width: 26px; height: 26px; object-fit: contain; flex: 0 0 26px; margin: -4px 0; }

/* 아이콘 옆 라벨의 세로 정렬 보정.
   flex의 align-items:center는 글리프가 아니라 '라인박스'를 기준으로 맞추는데,
   라인박스 높이는 폰트의 ascent/descent로 정해진다. 이 앱 폰트들은 descent가
   실제 글자보다 크게 잡혀 있어(고딕 15/5인데 실제 글리프는 15/3) 라인박스
   중심이 글자 중심보다 아래에 생기고, 그만큼 글자가 위로 떠 보인다.
   고딕 1px, Maple·8bit 0.5px 차이라 1px 내려주면 세 폰트 모두 맞는다. */
.icon-lbl { position: relative; top: 1px; }
/* 결정석은 아이콘이 세로로 길쭉해서 글자가 상대적으로 더 위로 떠 보인다는 지적.
   측정상으로는 1px에서 이미 잉크 중심이 맞지만, 눈으로는 1px 더 내린 쪽이
   맞아 보인다고 해서 여기만 2px로 둔다. 되돌리려면 이 규칙만 지우면 된다. */
.crystal-bar__type .icon-lbl { top: 2px; }
/* 레벨과 한 줄에 놓인 서버 아이콘·서버 이름은 레벨 글자와 중심 높이를 같게 둔다. 지수 기준: 사람 눈으로 볼 때 각 글자·그림의 가운데가 한 줄에 놓일 것.
   2026-11-02 화면의 기준선과 실제 칠해진 픽셀을 재서, 레벨 글자의 픽셀 중심에서 어긋난 만큼 옮겼다. 글꼴 높이 정보로 재면 1px 가까이 틀려서 쓰지 않는다.
   카드·글꼴마다 글자 크기와 모양이 달라 값이 다르다. 화면 폭에 따라 글자 크기가 바뀌어도 맞도록 서버 이름 글자 크기에 비례하는 em으로 둔다.
   그림의 em도 같은 글자 크기를 물려받는다. 아래 첫 묶음이 기본 글꼴 고딕, 그다음이 설정에서 고르는 다른 글꼴 */
:is(.char-card__world-line, .ci-server, .hc__server, .dt-card__server) img { position: relative; }
.char-card__world-line .icon-lbl { top: -0.04em; } .char-card__world-line img { top: -0.067em; }
.hc__server .icon-lbl { top: 0.114em; } .hc__server img { top: 0.0em; }
.dt-card__server .icon-lbl { top: 0.088em; } .dt-card__server img { top: 0.0em; }
body[data-font="8bit"] .char-card__world-line .icon-lbl { top: -0.055em; } body[data-font="8bit"] .char-card__world-line img { top: -0.094em; }
body[data-font="8bit"] .hc__server .icon-lbl { top: 0.006em; } body[data-font="8bit"] .hc__server img { top: -0.047em; }
body[data-font="8bit"] .dt-card__server .icon-lbl { top: -0.015em; } body[data-font="8bit"] .dt-card__server img { top: -0.046em; }
body[data-font="Maple"] .char-card__world-line .icon-lbl { top: 0.05em; } body[data-font="Maple"] .char-card__world-line img { top: -0.031em; }
body[data-font="Maple"] .hc__server .icon-lbl { top: -0.033em; } body[data-font="Maple"] .hc__server img { top: -0.047em; }
body[data-font="Maple"] .dt-card__server .icon-lbl { top: 0.012em; } body[data-font="Maple"] .dt-card__server img { top: -0.046em; }
body[data-font="Pretendard"] .char-card__world-line .icon-lbl { top: 0.05em; } body[data-font="Pretendard"] .char-card__world-line img { top: -0.01em; }
body[data-font="Pretendard"] .hc__server .icon-lbl { top: 0.035em; } body[data-font="Pretendard"] .hc__server img { top: -0.038em; }
body[data-font="Pretendard"] .dt-card__server .icon-lbl { top: 0.012em; } body[data-font="Pretendard"] .dt-card__server img { top: -0.037em; }
/* 폰 폭은 기준 글자 크기가 달라 글꼴이 픽셀을 반올림하는 자리가 바뀐다. em만으로는 0.5~2px 어긋나 390px 폭에서 따로 잰 값을 쓴다 */
@media (max-width: 768px) {
  body[data-font="고딕"] .char-card__world-line .icon-lbl { top: -0.034em; } body[data-font="고딕"] .char-card__world-line img { top: -0.080em; }
  body[data-font="고딕"] .hc__server .icon-lbl { top: 0.041em; } body[data-font="고딕"] .hc__server img { top: -0.011em; }
  body[data-font="고딕"] .dt-card__server .icon-lbl { top: 0.099em; } body[data-font="고딕"] .dt-card__server img { top: -0.011em; }
  body[data-font="Maple"] .char-card__world-line .icon-lbl { top: -0.017em; } body[data-font="Maple"] .char-card__world-line img { top: -0.044em; }
  body[data-font="Maple"] .hc__server .icon-lbl { top: 0.052em; } body[data-font="Maple"] .hc__server img { top: -0.046em; }
  body[data-font="Maple"] .dt-card__server .icon-lbl { top: 0.030em; } body[data-font="Maple"] .dt-card__server img { top: -0.044em; }
  body[data-font="8bit"] .char-card__world-line .icon-lbl { top: 0.037em; } body[data-font="8bit"] .char-card__world-line img { top: -0.023em; }
  body[data-font="8bit"] .hc__server .icon-lbl { top: 0.002em; } body[data-font="8bit"] .hc__server img { top: -0.046em; }
  body[data-font="8bit"] .dt-card__server .icon-lbl { top: -0.011em; } body[data-font="8bit"] .dt-card__server img { top: -0.044em; }
  body[data-font="Pretendard"] .char-card__world-line .icon-lbl { top: 0.072em; } body[data-font="Pretendard"] .char-card__world-line img { top: -0.011em; }
  body[data-font="Pretendard"] .hc__server .icon-lbl { top: 0.042em; } body[data-font="Pretendard"] .hc__server img { top: -0.026em; }
  body[data-font="Pretendard"] .dt-card__server .icon-lbl { top: 0.030em; } body[data-font="Pretendard"] .dt-card__server img { top: -0.024em; }
}
/* 캐릭터 목록 카드는 카드 폭에 따라 글자 크기가 계속 바뀌어, 글꼴이 픽셀을 반올림하는 자리가 폭마다 달라졌다.
   레벨·서버 이름의 줄 높이를 1로 고정하면 그 반올림이 사라져, 글꼴마다 하나의 em 값으로 360~1920px 폭에서 0.5px 안으로 맞는다.
   서버 이름은 말줄임 때문에 넘친 부분을 자르므로, 위아래 여백을 늘리고 같은 만큼 바깥 여백을 당겨 글자가 잘리지 않게 한다 */
.ci-lv, .ci-server .icon-lbl { line-height: 1; }
.ci-server .icon-lbl { padding: .15em 0; margin: -.15em 0; top: 0; }
.ci-server img { top: -0.042em; }
body[data-font="8bit"] .ci-server .icon-lbl { top: 0.051em; } body[data-font="8bit"] .ci-server img { top: -0.038em; }
body[data-font="Maple"] .ci-server .icon-lbl { top: 0; } body[data-font="Maple"] .ci-server img { top: -0.058em; }
body[data-font="Pretendard"] .ci-server .icon-lbl { top: 0.075em; } body[data-font="Pretendard"] .ci-server img { top: -0.027em; }
/* .ci-server는 말줄임을 쓰는데, 글자를 span으로 감싸면 잘림 처리가 그 span으로
   내려가야 하므로 같은 규칙을 물려준다. */
.ci-server .icon-lbl { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }


/* ── 메운디 ── */
.mu-keys { display: flex; flex-direction: column; gap: 4px; margin-top: 12px; }
.mu-chip { font-size: 1.05rem; font-weight: 800; color: var(--text); line-height: 1.5; word-break: keep-all; }
.mu-panel-h { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
:is(.mu-pip, .vp-pip, .lt-pip) { padding: 4px 14px; border-radius: 8px; border: none; background: var(--primary); color: #fff; font-size: .95rem; font-weight: 800; cursor: var(--cur-pointer); }
:is(.mu-pip, .vp-pip, .lt-pip):hover { filter: brightness(1.08); }
.mu-pay { margin-left: auto; font-size: .85rem; font-weight: 800; color: var(--accent); }
.mu-row { display: flex; align-items: center; gap: 12px; padding: 10px 0; border-top: 1px solid var(--border); }
.mu-head { flex: 0 0 104px; display: flex; flex-direction: column; align-items: center; gap: 4px; text-align: center; }
.mu-roll { font-size: .82rem; font-weight: 800; color: var(--text); white-space: nowrap; }
.mu-wave { font-size: .78rem; color: var(--text-sub); font-weight: 700; word-break: keep-all; }
.mu-cards { flex: 1; display: flex; flex-wrap: wrap; gap: 8px; }
.mu-card { padding: 6px; border-radius: 10px; border: 1.5px solid var(--border); background: var(--bg2); }
.mu-units { display: flex; gap: 4px; }
.mu-u { width: 52px; padding: 3px 3px 4px; border-radius: 9px; text-align: center; display: flex; flex-direction: column; align-items: center; gap: 1px; line-height: 1.2; color: #fff; }
.mu-u img { width: 46px; height: 46px; display: block; border-radius: 6px; background: rgba(255,255,255,.88); }
.mu-u span { font-size: .72rem; font-weight: 800; white-space: nowrap; }
.mu-u--r { background: #e5484d; } .mu-u--k { background: #2a2a33; } .mu-u--y { background: #d9a400; }
.mu-zero { opacity: .45; }
.mu-steps { margin: 8px 0 0 18px; padding: 0; display: flex; flex-direction: column; gap: 8px; line-height: 1.6; font-size: .88rem; word-break: keep-all; }
.mu-st { display: flex; gap: 12px; padding: 8px 0; border-top: 1px solid var(--border); font-size: .88rem; word-break: keep-all; }
.mu-st b { flex: 0 0 150px; }
@media (max-width: 520px) { .mu-row { flex-direction: column; align-items: flex-start; gap: 6px; } .mu-head { flex-direction: row; align-items: center; flex: none; } .mu-st { flex-direction: column; gap: 2px; } .mu-st b { flex: none; } }

.ci-exp { margin-top: 16px; }
.ci-exp__head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 10px; font-size: 1.2rem; font-weight: 800; color: var(--text-sub); }
.ci-exp__row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.ci-exp__row .card__title { font-size: 1rem; text-transform: none; margin-bottom: 8px; }
.ci-exp__svg { display: block; width: 100%; height: auto; overflow: visible; }
.ci-exp__axis { stroke: var(--border); stroke-width: 1; }
.ci-exp__bar { fill: var(--primary); fill-opacity: .8; }
.ci-exp__val { fill: var(--text); font-size: 12px; font-weight: 700; text-anchor: middle; }
.ci-exp__x { fill: var(--text-sub); font-size: 12px; font-weight: 600; text-anchor: middle; }
.ci-exp__area { fill: var(--primary); fill-opacity: .14; }
.ci-exp__line { fill: none; stroke: var(--primary); stroke-width: 2.5; stroke-linejoin: round; }
.ci-exp__dot { fill: var(--bg2); stroke: var(--primary); stroke-width: 2.5; }
.ci-looks { display: grid; grid-template-columns: repeat(7, 1fr); gap: 18px 8px; }
.ci-looks__item { display: flex; flex-direction: column; align-items: center; gap: 8px; }
@media (max-width: 760px) { .ci-looks { grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); } }
.ci-looks__item img { width: 96px; height: 96px; object-fit: contain; object-position: bottom center; image-rendering: pixelated; }
.ci-looks__item span { font-size: .82rem; font-weight: 700; color: var(--text-sub); }
@media (max-width: 760px) { .ci-exp__row { grid-template-columns: 1fr; } }

/* ── 사이드바 묶음 메뉴: 시뮬레이터·이벤트 게임 공략 ── */
.sb-group__head { width: 100%; }
.sb-group.has-active .sb-group__head { color: var(--text); }
.sb-group.open .sb-group__head {
  background-image: linear-gradient(90deg, rgba(var(--star),.30), rgba(var(--hue-l),.26));
  border: 1px solid rgba(var(--star),.4);
  color: var(--accent);
  box-shadow: 0 4px 16px rgba(0,0,0,.4), 0 0 12px rgba(var(--star),.08);
  text-shadow: 0 0 8px rgba(var(--star),.35);
}
.sb-group__list { display: none; flex-direction: column; margin: 2px 0 4px 14px; padding-left: 8px; border-left: 2px solid var(--border); }
.sb-group.open .sb-group__list { display: flex; }
.sb-group.open .sb-group__list:empty { display: none; }

/* ── 사이드바 즐겨찾기 별 (app.js renderFavs) ──
   메뉴 줄에 마우스를 올리면 빈 별, 즐겨찾기에 넣은 메뉴는 노란 별이 늘 보인다. 별 그림은 원본 크기 11×10 그대로.
   마우스가 없는 폰에서는 빈 별을 늘 보여 누를 자리를 알 수 있게 한다 */
.sb-fav {
  margin-left: auto; flex-shrink: 0; width: 22px; height: 30px; margin-right: -6px;
  display: inline-flex; align-items: center; justify-content: center;
  visibility: hidden; transition: transform .15s;
}
.sb-fav img { width: auto; height: auto; }
.sb-fav__on { display: none; }
.sb-nav__item:hover .sb-fav { visibility: visible; }
.sb-nav__item .sb-fav:hover { transform: scale(1.25); }
.sb-nav__item.is-fav .sb-fav, .sb-nav__item[data-fav] .sb-fav { visibility: visible; }
.sb-nav__item.is-fav .sb-fav__on, .sb-nav__item[data-fav] .sb-fav__on { display: block; }
.sb-nav__item.is-fav .sb-fav__off, .sb-nav__item[data-fav] .sb-fav__off { display: none; }
@media (hover: none) { .sb-fav { visibility: visible; } }
/* 즐겨찾기 줄의 순서 바꾸기 화살표. GMS v270 UI/Basic.img BtUP·BtDown의 normal·mouseOver·disabled, 원본 12×12 그대로.
   위·아래를 세로로 쌓아 줄 높이 안에 넣고, 평소에는 흐리게 두었다가 화살표에 직접 마우스를 올리면 또렷하게 보인다 */
.sb-mv { margin-left: auto; flex-shrink: 0; display: flex; flex-direction: column; gap: 1px; }
.sb-mv + .sb-fav { margin-left: 4px; }
.sb-mv__b { opacity: .25; transition: opacity .15s; }
.sb-mv__b:hover { opacity: 1; }
.sb-mv__b.is-off:hover { opacity: .25; }
@media (hover: none) { .sb-mv__b { opacity: .6; } }
.sb-mv__b { position: relative; width: 12px; height: 12px; background: no-repeat center / 12px 12px; image-rendering: pixelated; cursor: var(--cur-pointer); }
/* 12px는 손가락으로 누르기 작아 눈에 안 보이는 누르는 영역을 넓힌다 */
.sb-mv__b::after { content: ''; position: absolute; inset: -4px -5px -1px; }
.sb-mv__b--up { background-image: url(images/icons/fav_up.png); }
.sb-mv__b--up:hover { background-image: url(images/icons/fav_up_hover.png); }
.sb-mv__b--down { background-image: url(images/icons/fav_down.png); }
.sb-mv__b--down:hover { background-image: url(images/icons/fav_down_hover.png); }
.sb-mv__b--up.is-off { background-image: url(images/icons/fav_up_off.png); }
.sb-mv__b--down.is-off { background-image: url(images/icons/fav_down_off.png); }
.mu-ref { margin-top: 10px; font-size: .84rem; color: var(--text-sub); word-break: break-all; }
.mu-ref a { color: var(--primary); text-decoration: underline; }

/* ── 승리 포즈 연습 (victorypose.js) ──
   판은 지수가 고른 사이드킥 승리 포즈 그림에 어두운 막을 씌우고, 가운데에 적은 방향키, 아래에 누를 버튼을 둔다.
   키는 뒤 그림처럼 도트 그림이고 18×19칸이다. --vp-u는 적은 키의 한 칸, --vp-bu는 버튼의 한 칸 크기.
   판을 기준으로 한 cqw·cqh로 정해 이 화면과 PIP 창 어느 크기에서도 같은 비율로 보이고,
   round()를 쓰는 브라우저에서는 한 칸을 1px 단위로 맞춰 도트가 고르게 찍힌다.
   두 변수는 판 안의 요소에서 풀리므로 판 크기를 따른다. 판 자신의 속성에는 cq 단위를 쓰지 않는다 */
.vp-tools { display: flex; margin-bottom: 10px; }
.vp-board {
  --vp-u: calc(min(11cqw, 33cqh) / 18);
  --vp-bu: calc(min(9cqw, 26cqh) / 18);
  container-type: size; position: relative; width: 100%; max-width: 720px; aspect-ratio: 598 / 229;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  border-radius: 10px; overflow: hidden; user-select: none; isolation: isolate;
}
/* 그림 색이 진하다는 지수 의견으로 채도를 낮춘다. 그림에만 거르개를 걸려고 판 자체가 아닌 뒤 층에 깐다 */
.vp-board::before {
  content: ''; position: absolute; inset: 0; z-index: -1; filter: saturate(.62);
  background: linear-gradient(rgba(12,8,24,.52), rgba(12,8,24,.52)), url('images/victorypose/bg.webp?v=20261029a') center / cover;
}
@supports (width: round(1.5px, 1px)) {
  .vp-board { --vp-u: max(1px, round(calc(min(11cqw, 33cqh) / 18), 1px)); --vp-bu: max(1px, round(calc(min(9cqw, 26cqh) / 18), 1px)); }
}
.vp-seq { display: flex; justify-content: center; gap: 1.6cqw; height: calc(var(--vp-u) * 19); }
.vp-key { display: block; width: calc(var(--vp-u) * 18); height: calc(var(--vp-u) * 19); filter: drop-shadow(0 calc(var(--vp-u) * 2) 0 rgba(0,0,0,.35)); }
.vp-t { display: block; width: 100%; height: 100%; }
.vp-pad { display: flex; align-items: center; gap: 1.4cqw; margin-top: 7cqh; }
.vp-btn { display: block; width: calc(var(--vp-bu) * 18); height: calc(var(--vp-bu) * 19); }
.vp-btn:hover .vp-t { filter: brightness(1.2); }
/* 누르면 윗면이 내려가고 밝아진 그림으로 바꾼다. 마우스를 누르고 있는 동안과, 클릭·키 입력 뒤 잠깐 붙는 .is-press 동안 */
.vp-btn .vp-t--down,
:is(.vp-btn:active, .vp-btn.is-press) .vp-t:not(.vp-t--down) { display: none; }
:is(.vp-btn:active, .vp-btn.is-press) .vp-t--down { display: block; }
.vp-reset { display: inline-flex; align-items: center; gap: 1cqw; width: auto; margin-left: 1.6cqw; }
.vp-reset .vp-t { width: calc(var(--vp-bu) * 18); height: calc(var(--vp-bu) * 19); flex: none; }
.vp-reset span {
  color: #fff; font-size: calc(var(--vp-bu) * 7); font-weight: 900; line-height: 1;
  text-shadow: 2px 0 0 #3a1418, -2px 0 0 #3a1418, 0 2px 0 #3a1418, 0 -2px 0 #3a1418, 0 3px 4px rgba(0,0,0,.6);
}
/* PIP 창 — 판이 창 전체를 덮는다. 창 body에도 이 스타일시트가 걸려 모눈 배경과 장식이 있어 그 위를 덮는다 */
.vp-pip-body { margin: 0; overflow: hidden; background: #0c0818; }
.vp-board--pip { position: fixed; inset: 0; z-index: 1; width: auto; max-width: none; aspect-ratio: auto; border-radius: 0; }
@media (prefers-reduced-motion: no-preference) { .vp-key--new { animation: vpPop .18s cubic-bezier(.3,1.6,.5,1); } }
@keyframes vpPop { from { scale: .5; opacity: 0; } to { scale: 1; opacity: 1; } }

/* ── 특수 코어 타이머 · Lethal Strike I·Fatal Strike I (myutil.js) ──
   아이콘은 32×32 도트라 정수 배율로 픽셀 그대로 키운다. 다 세면 테두리와 글자를 금색으로 바꾼다 */
.lt-stack { display: flex; flex-direction: column; gap: 10px; }
.lt-board {
  display: flex; align-items: center; gap: 16px; max-width: 520px; padding: 14px 16px; border-radius: 10px;
  border: 1.5px solid var(--border); background: var(--bg2); user-select: none;
}
.lt-board[data-state="ready"] { border-color: rgb(var(--star)); box-shadow: inset 0 0 0 1px rgba(var(--star), .45); }
.lt-ico-wrap { position: relative; flex: none; width: 64px; height: 64px; }
.lt-ico { width: 64px; height: 64px; flex: none; image-rendering: pixelated; }
/* 효과·재발동 남은 초: 게임 버프 아이콘처럼 우측 상단에 노란 도트 숫자. 32×32 아이콘을 2배로 키웠으니 숫자도 11px 높이를 2배로 */
.lt-buffno { position: absolute; top: 0; right: 0; display: flex; }
/* 숫자판 digits.png는 0~9를 한 줄로 이어 붙인 77×11 그림. 1만 5px, 나머지는 8px 폭. 2배로 키워 숫자마다 위치만 옮긴다 */
.lt-buffno i {
  display: block; width: 16px; height: 22px; image-rendering: pixelated;
  background: url("images/myutil/num/digits.png?v=20261031a") 0 0 / 154px 22px no-repeat;
}
.lt-buffno .lt-d1 { width: 10px; background-position-x: -16px; }
.lt-buffno .lt-d2 { background-position-x: -26px; }
.lt-buffno .lt-d3 { background-position-x: -42px; }
.lt-buffno .lt-d4 { background-position-x: -58px; }
.lt-buffno .lt-d5 { background-position-x: -74px; }
.lt-buffno .lt-d6 { background-position-x: -90px; }
.lt-buffno .lt-d7 { background-position-x: -106px; }
.lt-buffno .lt-d8 { background-position-x: -122px; }
.lt-buffno .lt-d9 { background-position-x: -138px; }
/* 재발동을 기다리는 동안과 스위칭 중에는 게임의 회색 그림, 효과 중과 다시 발동할 수 있으면 컬러 */
.lt-ico--off, .lt-board:is([data-state="cool"], [data-state="swap"]) .lt-ico--on { display: none; }
.lt-board:is([data-state="cool"], [data-state="swap"]) .lt-ico--off { display: block; }
.lt-main { flex: 1; min-width: 0; }
.lt-name { display: flex; align-items: center; gap: 8px; font-size: .9rem; font-weight: 800; color: var(--text-sub); }
/* 코어마다 그 코어 하나만 띄우는 PIP 버튼. 이름 옆에 작게 */
.lt-name .lt-pip { padding: 1px 8px; border-radius: 6px; font-size: .72rem; }
/* 효과 중에는 테두리를 주 색으로 */
.lt-board[data-state="buff"] { border-color: var(--primary); }
/* 큰 숫자는 스위칭 60초만 센다. 코어가 발동해 세는 동안 서 있는 60은 흐리게 */
.lt-time { font-size: 2.4rem; font-weight: 900; line-height: 1.15; font-variant-numeric: tabular-nums; white-space: nowrap; }
.lt-board:is([data-state="buff"], [data-state="cool"]) .lt-time { color: var(--text-sub); opacity: .55; }
.lt-board[data-state="ready"] .lt-time { color: rgb(var(--star)); font-size: 1.9rem; }
.lt-bar { height: 6px; margin-top: 6px; border-radius: 3px; background: var(--border); overflow: hidden; }
.lt-bar i { display: block; width: 100%; height: 100%; background: var(--primary); }
/* 시작·초기화를 위아래로, 스위칭은 그 옆에 두 칸 높이로 */
.lt-btns { display: grid; grid-template-columns: auto auto; gap: 6px; flex: none; }
/* 좁은 화면에서는 버튼 넷을 판 아래 한 줄로 내려 큰 숫자 자리를 지킨다 */
@media (max-width: 520px) {
  .lt-board:not(.lt-board--pip) { flex-wrap: wrap; }
  .lt-board:not(.lt-board--pip) .lt-btns { width: 100%; grid-template-columns: repeat(4, 1fr); }
}
.lt-btns button {
  padding: 6px 16px; border-radius: 8px; border: 1.5px solid var(--border); background: var(--bg); color: var(--text);
  font-size: .9rem; font-weight: 800; cursor: var(--cur-pointer);
}
.lt-btns [data-lt="start"] { background: var(--primary); border-color: var(--primary); color: #fff; }
.lt-btns button:hover { filter: brightness(1.08); }
/* PIP 창 — 코어 판 하나가 창 전체를 덮는다. 배경 층 body::before보다 위에 오게 한다 */
.lt-pip-body { margin: 0; height: 100vh; overflow: hidden; display: flex; flex-direction: column; background: var(--bg2); }
.lt-board--pip { position: relative; z-index: 1; flex: 1; min-height: 0; max-width: none; gap: 12px; padding: 8px 14px; border-width: 0; border-radius: 0; }
/* 작은 창은 버튼 좌우 여백을 줄여 큰 글자 발동 가능이 잘리지 않게 한다 */
.lt-board--pip .lt-btns button { padding: 5px 10px; }
.lt-board--pip[data-state="ready"] .lt-time { font-size: 1.6rem; }
.lt-board--pip[data-state="ready"] { border-width: 2px; }
.sb-nav__icon--px { image-rendering: pixelated; }

/* ── 의문의 결계 시뮬레이터 (mysticseal.js) ──
   핵 그림은 도트라 키울 때 픽셀을 그대로 키운다. 희귀도 글자색은 잠재능력 등급색 --gt-*를 쓴다 */
.ms-tiers, .ms-cores, .ms-pick { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 6px; }
.ms-tiers, .ms-pick { margin-top: 8px; }
.ms-tier, .ms-pick button {
  display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 8px 2px; border-radius: 8px;
  border: 1.5px solid var(--border); background: var(--bg2); color: var(--text-sub); font-size: .74rem; font-weight: 700;
}
.ms-tier img { width: 33px; height: 34px; object-fit: contain; }
:is(.ms-tier, .ms-pick button):hover { border-color: rgba(var(--star),.5); }
:is(.ms-tier, .ms-pick button).active { border-color: rgb(var(--star)); background: rgba(var(--star),.12); color: var(--text); }
.ms-chip { display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 8px 2px; border-radius: 8px; background: var(--bg2); }
.ms-chip.is-zero { opacity: .4; }
.ms-chip small { font-size: .72rem; font-weight: 700; color: var(--text-sub); }
.ms-chip b { font-size: .9rem; font-weight: 900; color: var(--text); font-variant-numeric: tabular-nums; }
.ms-core { width: 34px; height: 35px; object-fit: contain; }
.ms-ico { display: inline-block; width: 16px; height: 16px; margin-right: 4px; vertical-align: -3px; object-fit: contain; image-rendering: pixelated; }
.ms-g { font-size: .78rem; font-weight: 800; color: var(--text-sub); }
.ms-g[data-g="1"] { color: var(--gt-rare); }
.ms-g[data-g="2"] { color: var(--gt-epic); }
.ms-g[data-g="3"] { color: var(--gt-unique); }
.ms-g[data-g="4"] { color: var(--gt-legendary); }
.ms-row { display: flex; gap: 8px; }
.ms-row .sel { flex: 1; width: auto; min-width: 0; }
.ms-row .sbtn { flex: 1; white-space: nowrap; }
.ms-now { display: flex; align-items: center; gap: 14px; padding: 12px 14px; border-radius: 10px; background: var(--bg2); }
.ms-now__img { width: 68px; height: 70px; object-fit: contain; image-rendering: pixelated; }
.ms-now .ms-g { display: block; font-size: .95rem; }
.ms-now b { font-size: 1.5rem; font-weight: 900; color: var(--accent); }
.ms-eff { margin-top: 8px; }
.ms-tbl-wrap { overflow-x: auto; margin-top: 8px; }
.ms-tbl { table-layout: auto; min-width: 560px; }
.ms-tbl th:first-child { width: auto; }
.ms-th-img { display: block; width: 28px; height: 28px; margin: 0 auto 2px; object-fit: contain; }
.ms-badge { display: inline-block; width: 22px; height: 22px; margin-right: 6px; vertical-align: middle; object-fit: contain; }

/* ── 믹스염색 시뮬레이터 (mixdye.js) ──
   왼쪽 목록 카드, 오른쪽 조절 카드 + 기준 원본·믹스 결과·믹스 원본 3칸 비교.
   캐릭터 그림은 96×96 도트라 정수 배율 + pixelated로만 키운다(흐려지지 않게). */
.mx-layout { display: grid; grid-template-columns: 320px minmax(0,1fr); gap: 16px; align-items: start; }
.mx-browser { position: sticky; top: calc(var(--top-h) + 12px); display: flex; flex-direction: column; gap: 8px; padding: 14px; height: calc(100vh - var(--top-h) - 40px); min-height: 420px; }
.mx-filter { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 10px; font-size: .78rem; color: var(--text-sub); }
.mx-check { display: inline-flex; align-items: center; gap: 6px; cursor: var(--cur-pointer); }
.mx-check input { accent-color: var(--primary); }
.mx-list { flex: 1; min-height: 0; overflow-y: auto; position: relative; margin: 0 -6px; padding: 0 6px; }
.mx-item { display: grid; grid-template-columns: 36px minmax(0,1fr); align-items: center; gap: 10px; width: 100%; padding: 6px 8px; border-radius: var(--radius); border: 1px solid transparent; text-align: left; }
.mx-item:hover { background: var(--bg-hover); }
.mx-item.active { background: var(--primary-l); border-color: var(--border-hl); }
/* 층 데이터가 없어 고를 수 없는 줄 */
.mx-item.is-off { opacity: .45; cursor: var(--cur-default); }
.mx-item.is-off:hover { background: none; }
.mx-item__icon { width: 36px; height: 36px; object-fit: none; }
.mx-item__text { display: flex; flex-direction: column; min-width: 0; }
.mx-item__en { font-size: .86rem; font-weight: 700; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mx-item__ko { font-size: .74rem; color: var(--text-sub); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mx-empty { padding: 20px 8px; text-align: center; font-size: .82rem; color: var(--text-sub); }

.mx-work { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.mx-sel { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; min-width: 0; }
.mx-sel__icon { width: 44px; height: 44px; object-fit: none; flex: none; }
.mx-sel__text { min-width: 0; }
.mx-sel__name { font-size: 1.15rem; font-weight: 900; color: var(--text); overflow-wrap: anywhere; }
.mx-sel__sub { font-size: .8rem; color: var(--text-sub); }
.mx-row { display: grid; grid-template-columns: 72px minmax(0,1fr); align-items: center; gap: 8px 12px; }
.mx-row + .mx-row { margin-top: 12px; }
.mx-label { font-size: .8rem; font-weight: 800; color: var(--text-sub); }
.mx-chips { display: grid; grid-template-columns: repeat(var(--mx-cols, 5), minmax(0,1fr)); gap: 6px; }
.mx-chip { display: flex; align-items: center; justify-content: center; gap: 7px; height: 34px; padding: 0 6px; min-width: 0; white-space: nowrap; border-radius: var(--radius-sm); border: 1px solid var(--border); background: rgba(255,255,255,.04); color: var(--text-sub); font-size: .82rem; font-weight: 700; transition: border-color .15s, color .15s; }
.mx-chip:hover:not(:disabled) { border-color: var(--border-hl); color: var(--text); }
.mx-chip.active { border-color: var(--primary); background: var(--primary-l); color: var(--text); box-shadow: 0 0 0 1px var(--primary); }
.mx-chip:disabled { opacity: .3; cursor: var(--cur-default); }
.mx-dot { width: 14px; height: 14px; border-radius: 3px; flex: none; box-shadow: inset 0 0 0 1px rgba(255,255,255,.35); }
.mx-slider { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.mx-readout { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; }
.mx-readout__val { font-size: 1.35rem; font-weight: 900; color: var(--text); font-variant-numeric: tabular-nums; }
.mx-readout__val span { margin: 0 5px; color: var(--text-dim); }
.mx-tools { display: flex; flex-wrap: wrap; gap: 6px; }
.mx-tools .sbtn { min-width: 40px; padding: 5px 11px; font-size: .78rem; }
.mx-tools .sbtn:disabled { opacity: .4; cursor: var(--cur-default); }
/* 슬라이더 왼쪽을 색으로 채우지 않는다. 채우면 채운 길이가 비율처럼 보여서 손잡이 위치로만 비율을 나타낸다 */
.mx-range { width: 100%; height: 26px; -webkit-appearance: none; appearance: none; background: transparent; cursor: var(--cur-pointer); }
.mx-range::-webkit-slider-runnable-track { height: 6px; border-radius: 3px; background: var(--border); }
.mx-range::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 18px; height: 18px; margin-top: -6px; border-radius: 50%; background: var(--primary); border: 2px solid var(--bg-card); }
.mx-range::-moz-range-track { height: 6px; border-radius: 3px; background: var(--border); }
.mx-range::-moz-range-progress { background: transparent; }
.mx-range::-moz-range-thumb { width: 14px; height: 14px; border-radius: 50%; background: var(--primary); border: 2px solid var(--bg-card); }
.mx-range:disabled { opacity: .4; }
.mx-ends { display: flex; justify-content: space-between; gap: 8px; font-size: .76rem; color: var(--text-sub); }
.mx-ends span { display: inline-flex; align-items: center; gap: 5px; }
.mx-ends .mx-dot { width: 10px; height: 10px; }

.mx-tab { display: inline-flex; align-items: center; gap: 8px; }
.mx-tab__icon { flex: none; }
.mx-viewbar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; }
.mx-viewtabs { margin-bottom: 0; }
.mx-viewtabs .sf-tab { padding: 7px 20px; font-size: .84rem; }
.mx-viewnote { font-size: .78rem; color: var(--text-sub); }

.mx-compare { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1.4fr) minmax(0,1fr); gap: 12px; align-items: end; }
.mx-card { padding: 12px; display: flex; flex-direction: column; gap: 10px; }
.mx-card--result { border-color: var(--border-hl); }
.mx-stage { position: relative; display: grid; place-items: center; border-radius: var(--radius); background: rgba(255,255,255,.05); border: 1px solid var(--border); padding: 8px 0; }
.mx-stage canvas { max-width: 100%; height: auto; image-rendering: pixelated; }
.mx-status { position: absolute; inset: 0; display: grid; place-content: center; justify-items: center; gap: 8px; border-radius: var(--radius); background: var(--panel-veil); font-size: .8rem; color: var(--text-sub); text-align: center; }
.mx-status.is-error { color: var(--danger); font-weight: 700; }
.mx-cap__title { font-size: .76rem; font-weight: 800; color: var(--text-sub); }
.mx-cap__val, .mx-combo__val { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 7px; font-size: .86rem; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
.mx-combo .card__title { font-size: .95rem; margin-bottom: 10px; }
.mx-combo__row { display: grid; grid-template-columns: 48px minmax(0,1fr); gap: 10px; align-items: center; }
.mx-combo__row + .mx-combo__row { margin-top: 6px; }
.mx-combo__val b { font-weight: 800; overflow-wrap: anywhere; }

@media (max-width: 920px) {
  .mx-layout { grid-template-columns: minmax(0,1fr); }
  .mx-browser { position: static; height: auto; min-height: 0; }
  .mx-list { flex: none; max-height: 40vh; }
}
@media (max-width: 768px) {
  .mx-compare { grid-template-columns: minmax(0,1fr) minmax(0,1fr); }
  .mx-card--result { grid-column: 1 / -1; order: -1; }
  .mx-row { grid-template-columns: minmax(0,1fr); gap: 6px; }
  .mx-chips { grid-template-columns: repeat(var(--mx-cols-m, 4), minmax(0,1fr)); }
}

/* ── PC 홈에서는 사이드바 없음 (app.js navigateTo의 body.on-home) ──
   홈 카드에 메뉴가 다 있어 홈에서는 사이드바를 빼고 본문을 전체 폭으로 쓴다.
   메뉴에 들어가면 .app 기본 두 칸 배치대로 사이드바가 왼쪽에 늘 펼쳐진다. 모바일 햄버거 드로어는 그대로 */
@media (min-width: 769px) {
  body.on-home .app { grid-template-columns: minmax(0,1fr); }
  body.on-home .sidebar { display: none; }
}
/* ── 캐릭터 영역을 홈에 둠 (body.char-home) ──
   캐릭터 명찰·결정석·수익은 사이드바 맨 위에 늘 있고, home.js mountHomeCharArea가 홈 머리 영역에도 복사해 둔다.
   폰은 원래 그 영역 안 설정 버튼을 썼다 — 홈 복사본에는 그 버튼을 빼므로 헤더 설정 버튼을 늘 보인다 */
@media (max-width: 768px) {
  body.char-home #headerBtnSettings { display: inline-flex; flex-shrink: 0; }
  /* 햄버거·로고·이름표·설정이 한 줄에 서므로 로고는 줄이지 않고 이름이 길면 이름표만 말줄임으로 줄인다 */
  body.char-home .header__logo { flex-shrink: 0; }
  body.char-home .header__right, body.char-home #headerBtnAuth { min-width: 0; }
}

.mx-source { margin-top: -10px; }
.mx-source a { color: var(--primary); text-decoration: underline; }

/* ── 코디 시뮬레이터 코디 탭 (mixdye.js) ──
   #sec-mixdye.is-coordi일 때 색 조절·기준/믹스 원본 칸을 숨기고 부위 칩과 착용 결과 한 칸을 보인다 */
.mx-lists { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.mx-only-coordi { display: none; }
#sec-mixdye.is-coordi .mx-only-coordi { display: block; }
#sec-mixdye.is-coordi .mx-slots.mx-only-coordi { display: grid; }
#sec-mixdye.is-coordi .mx-no-coordi { display: none; }
.mx-slots { grid-template-columns: repeat(5, minmax(0,1fr)); gap: 5px; }
.mx-slot { height: 30px; padding: 0 2px; letter-spacing: -.3px; border-radius: var(--radius-sm); border: 1px solid var(--border); background: rgba(255,255,255,.04); color: var(--text-sub); font-size: .72rem; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; position: relative; }
.mx-slot:hover { border-color: var(--border-hl); color: var(--text); }
.mx-slot.active { border-color: var(--primary); background: var(--primary-l); color: var(--text); box-shadow: 0 0 0 1px var(--primary); }
.mx-slot.is-worn::after { content: ''; position: absolute; top: 4px; right: 4px; width: 6px; height: 6px; border-radius: 50%; background: var(--accent); }
.mx-hint { font-size: .78rem; color: var(--text-sub); margin-top: 4px; }
#sec-mixdye.is-coordi .mx-compare { grid-template-columns: minmax(0,1fr); justify-items: center; }
#sec-mixdye.is-coordi .mx-card--result { width: min(100%, 420px); }
.mx-unwear { padding: 2px 10px; font-size: .78rem; margin-left: 4px; }
@media (max-width: 768px) {
  .mx-slots { grid-template-columns: repeat(4, minmax(0,1fr)); }
  #sec-mixdye.is-coordi .mx-card--result { grid-column: auto; }
}

/* 코디 시뮬레이터 성별 선택 · 기본 옷 표시 */
.mx-topbar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; }
.mx-topbar .sf-tabs { margin-bottom: 0; }
.mx-sextabs .sf-tab { padding: 10px 20px; }
/* 캐릭터 창의 기본 캐릭터 성별. 코디 시뮬레이터 성별 버튼과 같은 모양 */
.char-sextabs { margin-bottom: 0; }
.char-sextabs .sf-tab { padding: 8px 20px; }
.mx-basic { font-size: .74rem; font-weight: 700; color: var(--text-dim); padding: 2px 8px; border: 1px solid var(--border); border-radius: var(--radius-sm); margin-left: 4px; }
#sec-mixdye.is-coordi .mx-check.mx-only-coordi { display: inline-flex; }
.mx-combo__head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px; }
.mx-combo__head .card__title { margin-bottom: 0; }
.mx-reset { padding: 5px 12px; font-size: .78rem; }
.mx-matte { margin-left: 10px; padding: 2px 8px; font-size: .74rem; font-style: normal; font-weight: 800; color: var(--accent); border: 1px solid var(--accent); border-radius: var(--radius-sm); vertical-align: middle; }

/* 코디 시뮬레이터 피부 탭 — 코디 탭처럼 결과 한 칸만 보이고, 컬러라인 피부는 선 색 슬라이더 */
.mx-only-skin { display: none; }
#sec-mixdye.is-skin .mx-only-skin { display: block; }
#sec-mixdye.is-skin .mx-no-coordi { display: none; }
#sec-mixdye.is-skin .mx-compare { grid-template-columns: minmax(0,1fr); justify-items: center; }
#sec-mixdye.is-skin .mx-card--result { width: min(100%, 420px); }
.mx-line-row { display: flex; align-items: center; gap: 12px; min-width: 0; }
.mx-line-row .mx-range { flex: 1; min-width: 0; }
.mx-line-val { min-width: 3ch; text-align: right; font-variant-numeric: tabular-nums; color: var(--text); }
.mx-line-swatch { width: 40px; height: 22px; border-radius: var(--radius-sm); box-shadow: inset 0 0 0 1px rgba(255,255,255,.35); }
.mx-line-reset { padding: 5px 12px; font-size: .78rem; }
#mxLineBox .mx-row + .mx-row { margin-top: 10px; }
.mx-notice { margin-top: -10px; color: var(--accent); }
/* 피부 미리보기: 96×96 맨몸 그림에서 머리 부분만 원본 크기로 */
.mx-item__icon.mx-skin-icon { object-fit: none; object-position: -30px -22px; }
.mx-sel__icon.mx-skin-icon { object-fit: none; object-position: -26px -18px; }

/* ── 코디 시뮬레이터 편의 기능: 배율·좌우 반전·되돌리기·프리셋·찜 ── */
#sec-mixdye.is-flip .mx-stage canvas { transform: scaleX(-1); }
.mx-flip.active { border-color: rgb(var(--star)); color: var(--accent); }
.mx-zoom:disabled { opacity: .35; cursor: var(--cur-default); }
.mx-histbtns { display: flex; gap: 6px; }
.mx-combo__acts { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 6px; }
.mx-preset-slots { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 8px; }
.mx-preset {
  position: relative; display: grid; place-items: center; aspect-ratio: 1; border-radius: 10px;
  border: 1.5px solid var(--border); background: rgba(255,255,255,.04); overflow: hidden;
}
.mx-preset:hover { border-color: rgba(var(--star),.5); }
.mx-preset.active { border-color: rgb(var(--star)); box-shadow: 0 0 0 2px rgba(var(--star),.25); }
.mx-preset__img { width: 100%; height: 100%; object-fit: contain; image-rendering: pixelated; }
.mx-preset__plus { font-size: 1.4rem; font-weight: 300; color: var(--text-sub); }
.mx-preset__n {
  position: absolute; left: 6px; top: 5px; min-width: 18px; height: 18px; padding: 0 5px; border-radius: var(--radius-pill);
  display: grid; place-items: center; background: var(--bg3); color: var(--text-sub); font-size: .68rem; font-weight: 900;
}
.mx-preset.active .mx-preset__n { background: rgb(var(--star)); color: #2a1d05; }
.mx-showtabs { display: inline-flex; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.mx-show { padding: 4px 10px; font-size: .76rem; font-weight: 700; color: var(--text-sub); }
.mx-show + .mx-show { border-left: 1px solid var(--border); }
.mx-show.active { background: var(--primary-l); color: var(--text); }
/* 최근 보기는 고른 차례로 줄을 세우려고 order를 쓴다 */
.mx-list { display: flex; flex-direction: column; }
.mx-list .mx-empty { order: 99999; }
.mx-item { grid-template-columns: 36px minmax(0,1fr) auto; }
.mx-item__fav { font-size: .95rem; line-height: 1; padding: 4px; color: var(--text-sub); opacity: .35; transition: opacity .15s, color .15s, transform .15s; }
.mx-item:hover .mx-item__fav { opacity: .7; }
.mx-item__fav:hover { transform: scale(1.2); }
.mx-item.is-fav .mx-item__fav { color: rgb(var(--star)); opacity: 1; }

/* ── 에르다 링크 erdalink.js ──
   에렐 라이트·시아 아스텔 캐릭터로 헥사 탭을 열면 헥사 목록 대신 뜬다.
   판 안의 그림은 모두 게임 파일 그대로라 테마와 상관없이 게임 색을 쓴다. 판 밖의 카드·버튼만 사이트 색을 따른다.
   판 좌표는 게임과 같은 px이고, .el-stage 전체를 transform으로 옮기고 키운다 */
.el-layout { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 16px; align-items: start; }
.el-side { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.el-board { padding: 16px; min-width: 0; }
.el-board__head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 12px; }
.el-board__head .card__title { margin-bottom: 0; }
.el-fit { padding: 6px 12px; font-size: .76rem; flex-shrink: 0; }
.el-view {
  position: relative; width: 100%; aspect-ratio: 1560 / 1200; max-height: 72vh; min-height: 240px;
  overflow: hidden; border-radius: var(--radius-sm); border: 1px solid var(--border); background: #1a1440;
  touch-action: none; user-select: none; -webkit-user-select: none; overscroll-behavior: contain;
}
.el-stage { position: absolute; left: 0; top: 0; transform-origin: 0 0; will-change: transform; }
.el-stage img, .el-shine img { position: absolute; max-width: none; pointer-events: none; image-rendering: pixelated; }
.el-stage .el-bg, .el-stage .el-deco, .el-shine .el-bg { image-rendering: auto; }
.el-bg { left: 0; top: 0; }
.el-line { opacity: .35; transition: opacity .2s; }
.el-line.is-on { opacity: 1; }
.el-line.is-plan { opacity: .8; filter: drop-shadow(0 0 3px rgb(var(--star))); }
/* 스톤은 크기 0인 단추를 가운데 점에 두고, 그림을 그 점 기준으로 붙인다. 누르는 자리는 ::before 원 */
.el-st { position: absolute; width: 0; height: 0; padding: 0; border: 0; background: none; cursor: var(--cur-pointer); }
.el-st::before { content: ''; position: absolute; left: -30px; top: -30px; width: 60px; height: 60px; border-radius: 50%; }
.el-st--origin::before { left: -22px; top: -22px; width: 44px; height: 44px; }
.el-st--SHINE::before { left: -28px; top: -28px; width: 56px; height: 56px; }
.el-st:focus-visible { outline: none; }
.el-st:focus-visible::before { box-shadow: 0 0 0 3px rgb(var(--star)); }
.el-lv { position: absolute; width: 0; height: 0; }
.el-ico--on, .el-ico--mo { display: none; }
.el-st.is-on .el-ico--off { display: none; }
.el-st.is-on .el-ico--on { display: block; }
@media (hover: hover) { .el-st:hover .el-ico--mo { display: block; } }
/* 오리진 스톤은 게임 파일에 꺼진 아이콘이 따로 없어 같은 그림을 어둡게 둔다 */
.el-st--origin:not(.is-on) .el-ico { filter: grayscale(1) brightness(.7); }
.el-act, .el-lock, .el-sel { display: none; }
.el-st.is-act .el-act { display: block; animation: el-pulse 1.6s ease-in-out infinite; }
.el-st.is-lock .el-lock, .el-lock.is-fixed { display: block; }
.el-st.is-sel .el-sel { display: block; }
/* 목표가 현재보다 높은 스톤 */
.el-st.is-plan .el-frame { filter: drop-shadow(0 0 5px rgb(var(--star))) drop-shadow(0 0 2px rgb(var(--star))); }
@keyframes el-pulse { 0%, 100% { opacity: .45; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .el-st.is-act .el-act { animation: none; } }

/* SHINE 판. 원래 509px을 넘지 않고, 좁으면 erdalink.js가 비율대로 줄인다 */
.el-shine { position: relative; width: 100%; max-width: 509px; margin: 12px auto 0; overflow: hidden; }
.el-shine__in { position: absolute; left: 0; top: 0; transform-origin: 0 0; }

/* 스톤 정보 */
.el-detail .empty { padding: 20px; }
.el-dt__head { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
.el-dt__ico {
  width: 52px; height: 52px; flex-shrink: 0; display: grid; place-items: center;
  background: #1a1440; border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.el-dt__ico img { image-rendering: pixelated; }
.el-dt__name { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; min-width: 0; }
.el-dt__name b { font-size: 1rem; font-weight: 800; color: var(--text); overflow-wrap: anywhere; }
.el-dt__desc {
  font-size: .8rem; line-height: 1.6; color: var(--text-sub); white-space: pre-line; overflow-wrap: anywhere;
  background: var(--bg3); border-radius: var(--radius-sm); padding: 10px 12px; max-height: 180px; overflow-y: auto;
}
.el-hl { color: var(--accent); font-weight: 700; }
.el-dt__sub { font-size: .78rem; font-weight: 900; color: var(--text-dim); letter-spacing: .8px; margin: 16px 0 6px; }
.el-conds { display: flex; flex-direction: column; gap: 6px; }
.el-cond {
  display: flex; justify-content: space-between; align-items: center; gap: 8px;
  font-size: .82rem; color: var(--text); background: var(--bg3); padding: 7px 10px; border-radius: var(--radius-sm);
}
.el-cond__ok { font-size: .74rem; font-weight: 800; flex-shrink: 0; }
.el-cond__ok.is-ok { color: var(--success); }
.el-cond__ok.is-ng { color: var(--danger); }
.el-dt__lock { margin-top: 14px; font-size: .86rem; font-weight: 800; color: var(--text-dim); }
.el-inputs { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; margin-top: 16px; }
.el-in { display: flex; flex-direction: column; gap: 5px; font-size: .78rem; font-weight: 700; color: var(--text-sub); }
.el-in .inp { width: 92px; }
.el-in__max { font-size: .74rem; color: var(--text-dim); padding-bottom: 11px; }
.el-tg { display: inline-flex; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.el-tg button { padding: 8px 14px; font-size: .8rem; font-weight: 700; color: var(--text-sub); cursor: var(--cur-pointer); transition: background .15s, color .15s; }
.el-tg button + button { border-left: 1px solid var(--border); }
.el-tg button:hover { color: var(--text); }
.el-tg button.active { background: var(--btn); color: var(--on-btn); }
.el-detail .hexa-result { gap: 0; }
/* 조 단위 메소처럼 값이 길면 이름은 한 줄로 두고 값만 줄바꿈한다 */
.el-row { gap: 10px; }
.el-row .rl { flex-shrink: 0; }
.el-row .rv { min-width: 0; }
.el-row__v { text-align: right; overflow-wrap: anywhere; }

@media (max-width: 1100px) {
  .el-layout { grid-template-columns: 1fr; }
}
@media (max-width: 768px) {
  .el-board { padding: 12px; }
  .el-view { max-height: 62vh; }
  .el-fit { padding: 5px 10px; }
}

/* 본문 맨 아래 넥슨 권리 안내 */
.site-notice { margin: 32px 0 8px; padding-top: 14px; border-top: 1px solid var(--border); font-size: .72rem; line-height: 1.6; color: var(--text-sub); text-align: center; }

/* 해방 계산기 보스 칸 — 게임 보스 목록 아이콘은 테두리가 그림에 들어 있어 칸 테두리·배경 없이 꽉 채운다 */
.boss-thumb--icon { border: 0; background: none; border-radius: 0; }
.boss-thumb--icon img { object-fit: contain; }
/* 해방 카드의 64px 칸은 .gen-boss .boss-thumb img의 cover가 더 강해서 66×67 아이콘 위아래와 모서리가 잘렸다.
   아이콘 원래 크기로 자르지 않고 그대로 보여 준다 */
.gen-boss .boss-thumb--icon { width: 66px; height: 67px; border-radius: 0; overflow: visible; }
.gen-boss .boss-thumb--icon img { width: 66px; height: 67px; object-fit: contain; }

/* 헥사 코어 아이콘은 게임의 32px 그림이다. 원래 크기 그대로 두고, 고해상도 화면에서도 번지지 않게 픽셀 그대로 키운다 */
.hx-node-name .hx-node-icon { width: 32px; height: 32px; image-rendering: pixelated; }

/* 헥사 오른쪽 열: 합계 결과 카드 아래에 코어별 필요량 카드 */
.hx-side { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.hx-core-list { display: flex; flex-direction: column; gap: 8px; container-type: inline-size; }
.hx-core-cat { margin: 8px 0 0; }
.hx-core-cat:first-child { margin-top: 0; }
.hx-core-row {
  display: grid; grid-template-columns: 32px minmax(0, 1fr) auto; align-items: center; gap: 4px 10px;
  background: var(--bg3); padding: 6px 12px; border-radius: var(--radius-sm);
}
.hx-core-row.is-done { opacity: .55; }
.hx-core-ico { width: 32px; height: 32px; display: inline-flex; }
.hx-core-ico .hx-node-icon { width: 32px; height: 32px; image-rendering: pixelated; }
.hx-core-main { min-width: 0; display: flex; flex-direction: column; gap: 6px; }
/* 긴 코어 이름은 왼쪽 입력 목록처럼 잘라 내지 않고 줄을 바꾼다. 레벨은 이름 끝에 이어 붙고 자리가 없으면 다음 줄로 */
.hx-core-head { line-height: 1.3; overflow-wrap: anywhere; }
.hx-core-name { font-weight: 700; font-size: .88rem; color: var(--text); }
.hx-core-lv { font-size: .75rem; color: var(--text-sub); white-space: nowrap; margin-left: 6px; }
.hx-core-prog { display: flex; align-items: center; gap: 8px; }
.hx-core-bar { flex: 1; height: 6px; border-radius: 3px; background: var(--border); overflow: hidden; }
.hx-core-bar i { display: block; height: 100%; background: var(--accent); border-radius: inherit; }
.hx-core-pct { font-size: .72rem; color: var(--text-sub); min-width: 2.6em; text-align: right; font-variant-numeric: tabular-nums; }
.hx-core-vals { display: flex; align-items: center; gap: 6px; }
.hx-core-val { display: inline-flex; align-items: center; justify-content: flex-end; gap: 2px; font-weight: 800; font-size: .92rem; color: var(--text); font-variant-numeric: tabular-nums; }
.hx-core-val--se { min-width: 4.4em; }
.hx-core-val--sef { min-width: 5.6em; }
/* 목록 폭이 좁으면 폰이든 사이드바가 열린 좁은 PC 창이든 값 두 개를 이름·막대 아래 줄로 내린다 */
@container (max-width: 440px) {
  .hx-core-row { grid-template-columns: 32px minmax(0, 1fr); }
  .hx-core-vals { grid-column: 1 / -1; justify-content: flex-end; }
}

/* 헥사 왼쪽 카드 제목 줄 */
.hx-card-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; }
.hx-card-head .card__title { margin-bottom: 0; }

/* 헤더 게임 이름 한글·영어 스위치. 테마 스위치 모양을 그대로 쓰고 영어일 때 손잡이가 오른쪽으로 간다. common.js nameLang */
.name-lang .theme-toggle.is-en { background: rgba(var(--hue),.22); }
.name-lang .theme-toggle.is-en .theme-toggle__knob { transform: translateX(18px); }

/* 게임 파일 원본 그림 — images/official. 픽셀 그림이라 원래 크기로 두거나 정수배로만 키우고, 키울 때는 픽셀 그대로 키운다 */
/* 보스 정보 카드·드랍 팝업의 보스 목록 아이콘 66×67 — 카드는 2배, 팝업은 3배 */
.bhp-card__img img[src^="images/official/boss/"] { width: 132px; height: 134px; object-fit: contain; image-rendering: pixelated; }
.bhp-drop-modal__img img[src^="images/official/boss/"] { width: 198px; height: 201px; image-rendering: pixelated; }
/* 대여템 칸 — 아이템 아이콘을 원래 크기로 칸 가운데에 둔다 */
.rental-slot { display: flex; align-items: center; justify-content: center; background: var(--bg3); }
.rental-slot img { width: auto; height: auto; max-width: 100%; max-height: 100%; }
/* 아케인·어센틱 포스 아이콘 19×19, 18×20 — 원래 크기 */
.force-icon { width: auto; height: auto; }
/* 미스틱 프론티어 속성·타입 아이콘은 13~23px이라 24px 칸 가운데에 원래 크기로 둔다 */
.fr-dd__trigger img[src*="/frontier/attr/"], .fr-dd__item img[src*="/frontier/attr/"] { width: 24px; height: 24px; object-fit: none; }
.wc-result__world[src*="/world_px/"] { width: 26px; height: 26px; flex-basis: 26px; margin: -4px 0; }

/* 의문의 결계 시뮬레이터 공식 그림 — images/mysticseal/official/.
   도트 그림인 제어봉·핵은 원래 크기 그대로 정수 배율로 픽셀을 살려 보이고,
   결계 에너지는 70px 그림을 꼭 절반인 35px로 줄여 고해상도 화면에서는 원래 픽셀 그대로 보인다.
   티어 그림도 도트 훈장 아이콘이라 원래 크기 그대로 두고, 높이가 31~35px로 달라 버튼 아래쪽에 맞춰 이름 줄을 가지런히 한다 */
.ms-ico { vertical-align: middle; }
.ms-ico--rod { width: 26px; height: 26px; margin-right: 6px; image-rendering: pixelated; }
/* 에너지는 게임 원본 70×70인데 작은 원본이 게임 파일에 없어, 지수 요청으로 제어봉과 같은 26px로 줄여 쓴다 */
.ms-ico--energy { width: 26px; height: 26px; margin-right: 6px; image-rendering: auto; }
.ms-core, .ms-th-img { width: auto; height: auto; image-rendering: pixelated; }
.ms-now__img { width: auto; height: auto; image-rendering: pixelated; }
.ms-tier { justify-content: flex-end; }
.ms-tier img { width: auto; height: auto; image-rendering: pixelated; }
.ms-badge { width: auto; height: auto; image-rendering: pixelated; }

/* 보스 정보 카드의 게임 큰 보스 그림 422×500 — 칸을 그림과 같은 비율로 세로로 늘려 위아래가 잘리지 않게 한다 */
.bhp-card__img--art { aspect-ratio: 422 / 500; }
.bhp-card__img img.bhp-card__art { width: 100%; height: 100%; object-fit: cover; object-position: center top; image-rendering: auto; }

/* 캐릭터 추가 창 서버 고르기: 칸마다 서버 아이콘이 왼쪽에 붙는다 */
.world-dd { position: relative; }
.world-dd__btn, .world-dd__opt {
  display: flex; align-items: center; gap: 8px; width: 100%; text-align: left; cursor: pointer;
  font: inherit; font-size: .86rem; color: var(--text); background: none; border: 0;
}
.world-dd__btn {
  height: 40px; padding: 0 12px; background: rgba(255,255,255,.06);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.world-dd__btn img, .world-dd__opt img, .world-dd__none { width: 26px; height: 28px; object-fit: contain; flex: none; image-rendering: pixelated; }
.world-dd__arrow { margin-left: auto; color: var(--text-sub); }
.world-dd__list {
  position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 20; max-height: 280px; overflow-y: auto;
  background: var(--bg2, #fff); border: 1px solid var(--border); border-radius: var(--radius-sm);
  box-shadow: 0 10px 28px rgba(0,0,0,.28); padding: 4px;
}
.world-dd__grp { padding: 6px 10px 2px; font-size: .72rem; font-weight: 800; color: var(--text-sub); }
.world-dd__opt { padding: 6px 10px; border-radius: 6px; }
.world-dd__opt.is-sub { padding-left: 18px; }
.world-dd__opt:hover, .world-dd__opt:focus-visible, .world-dd__opt.is-cur { background: rgba(var(--star), .18); }
