/* MLS student.css — 학생앱 정본(다크 판타지) 공용 셸
   tokens.css 를 먼저 링크한 뒤 사용한다. */

/* ── 화면 셸 ─────────────────────────────── */
.app{
  position:relative; min-height:100dvh;          /* ⚠ 100vh 금지: 안드로이드 크롬에서 하단이 잘린다 */
  max-width:520px; margin:0 auto;
  padding-bottom:calc(var(--tabbar-h) + env(safe-area-inset-bottom) + 16px);
  overflow-x:hidden;
}
.scroll{padding:0 var(--gut)}

/* 밤하늘 배경 — 시안용 CSS 드로잉. 정식 아트는 시안 승인 후 발주(brief §6) */
.sky{position:fixed;inset:0;z-index:-2;background:
  radial-gradient(120% 70% at 50% 0%, #2A2058 0%, #1B1640 45%, #141033 100%)}
.sky::after{content:"";position:absolute;inset:0;opacity:.75;background-image:
  radial-gradient(1.5px 1.5px at 12% 14%, #fff 50%, transparent 51%),
  radial-gradient(1.5px 1.5px at 78% 9%,  #fff 50%, transparent 51%),
  radial-gradient(1px 1px   at 34% 26%,  #E8DFFF 50%, transparent 51%),
  radial-gradient(1.5px 1.5px at 62% 32%, #fff 50%, transparent 51%),
  radial-gradient(1px 1px   at 88% 24%,  #CDBEFF 50%, transparent 51%),
  radial-gradient(1px 1px   at 22% 40%,  #fff 50%, transparent 51%),
  radial-gradient(1.5px 1.5px at 50% 46%, #E8DFFF 50%, transparent 51%);
  animation:twinkle 4.5s ease-in-out infinite}
@keyframes twinkle{0%,100%{opacity:.75}50%{opacity:.35}}
.glow{position:fixed;left:50%;top:-120px;width:420px;height:420px;transform:translateX(-50%);
  z-index:-1;pointer-events:none;
  background:radial-gradient(circle, rgba(138,92,240,.30) 0%, transparent 65%)}

/* ── 헤더 ────────────────────────────────
   320px 에서 코인칩이 카드 밖으로 나가지 않게 그리드 + min-width:0 을 전부 채운다 */
.hdr{
  display:grid; grid-template-columns:auto minmax(0,1fr) auto;
  grid-template-rows:auto auto; gap:6px var(--sp-3);
  align-items:center;
  margin:var(--sp-3) var(--gut) var(--sp-4);
  padding:var(--sp-3); border-radius:var(--r-20);
  background:var(--bg-glass); border:1px solid var(--line);
  backdrop-filter:blur(8px);
}
.hdr .av{grid-row:1/3;width:48px;height:48px;border-radius:50%;flex:none;
  border:2px solid var(--gold-500);background:var(--navy-600);object-fit:cover}
.hdr .who{grid-column:2;grid-row:1;display:flex;align-items:center;gap:6px;min-width:0}
.hdr .nm{font-size:var(--fs-15);font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.hdr .lv{flex:none;font-size:var(--fs-12);font-weight:700;color:#2A1E00;
  background:linear-gradient(180deg,var(--gold-400),var(--gold-500));
  padding:2px 8px;border-radius:var(--r-pill)}
.hdr .bell{grid-column:3;grid-row:1/3;align-self:center;position:relative}
.hdr .bell .dot{position:absolute;top:9px;right:9px;width:7px;height:7px;border-radius:50%;
  background:var(--danger);border:1.5px solid var(--navy-700)}

.xprow{grid-column:2;grid-row:2;display:flex;align-items:center;gap:var(--sp-2);min-width:0}
.xprow .bar{flex:1 1 auto;min-width:0;height:6px}
.xprow .bar>i{background:linear-gradient(90deg,var(--violet-400),var(--gold-400))}
.xprow .xpnum{flex:none;font-size:11px;color:var(--text-dim);font-variant-numeric:tabular-nums}
.wallet{grid-column:3;grid-row:2;justify-self:end;min-width:0;max-width:100%}
.chip{display:inline-flex;align-items:center;gap:5px;min-width:0;max-width:100%;
  padding:3px 8px;border-radius:var(--r-pill);
  background:rgba(242,199,92,.16);border:1px solid rgba(242,199,92,.4)}
.chip img{width:16px;height:16px;flex:none}
.chip .num{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-size:var(--fs-13);font-weight:700;color:var(--gold-400);font-variant-numeric:tabular-nums}

/* 좁은 폭(폴드2 커버)에서는 헤더를 더 눌러 쓴다 */
@media (max-width:344px){
  /* padding 이 곧 '칩이 카드 안쪽으로 들어간 거리'다. 12px 미만이면 감리 완료 조건에 걸린다 */
  .hdr{padding:12px;gap:5px var(--sp-2)}
  .hdr .av{width:42px;height:42px}
  .hdr .nm{font-size:var(--fs-13)}
}

/* ── 섹션·카드 ───────────────────────────── */
.sec-h{display:flex;align-items:center;justify-content:space-between;
  margin:var(--sp-5) 0 var(--sp-3);font-size:var(--fs-17);font-weight:700}
.card{background:var(--bg-glass);border:1px solid var(--line);border-radius:var(--r-20);
  padding:var(--sp-4);backdrop-filter:blur(6px)}

/* ── CTA ─────────────────────────────────── */
.cta{position:fixed;left:0;right:0;
  bottom:calc(var(--tabbar-h) + env(safe-area-inset-bottom) + 10px);
  padding:0 var(--gut);z-index:5;max-width:520px;margin:0 auto}
.btn{display:flex;align-items:center;justify-content:center;gap:8px;width:100%;
  min-height:var(--btn-h-lg);border-radius:var(--r-pill);font-weight:700;font-size:var(--fs-15);
  color:#fff;background:linear-gradient(180deg,var(--violet-400),var(--violet-500));
  box-shadow:0 6px 20px rgba(138,92,240,.45), inset 0 1px 0 rgba(255,255,255,.35);
  border:1px solid rgba(255,255,255,.18)}
.btn.gold{color:#2A1E00;background:linear-gradient(180deg,var(--gold-400),var(--gold-500));
  box-shadow:0 6px 20px rgba(242,199,92,.35), inset 0 1px 0 rgba(255,255,255,.5)}

/* ── 월드(배경 아트 무대) — 학생앱 전 화면 공통 골조 ──
   기본 비율 360:540. 내용이 길어 CTA 가 밀리는 화면은 .world.short(360:420)로 잘라 쓴다.
   ⚠ 배경에 scale/translate 를 걸지 마라 — 오브젝트는 컨테이너 %로 찍히므로 배경만 움직이면 어긋난다. */
.world{position:relative;width:100%;aspect-ratio:360/540;overflow:hidden}
.world.short{aspect-ratio:360/420}
.world>img.bg{width:100%;height:100%;object-fit:cover;display:block}
.world::after{content:"";position:absolute;inset:auto 0 0;height:64px;pointer-events:none;
  background:linear-gradient(180deg,rgba(11,8,33,0),#0B0821)}

/* L2 배경 패럴랙스 — 좌표를 가진 기본판(.world>img.bg)은 절대 움직이지 않는다(§4 함정 참조).
   이 레이어는 좌표가 없는 순수 장식이라 안전하게 움직여도 노드와 어긋나지 않는다.
   기본판과 다른 속도로 흘러야 "레이어가 다르게 밀린다"는 원문 정의를 만족한다. */
.parallax{position:absolute;inset:-6% -10%;pointer-events:none;z-index:1;opacity:.5;
  background-image:
    radial-gradient(1.4px 1.4px at 15% 22%, rgba(255,255,255,.9), transparent 60%),
    radial-gradient(1px 1px at 68% 14%, rgba(200,180,255,.8), transparent 60%),
    radial-gradient(1.2px 1.2px at 40% 48%, rgba(255,255,255,.7), transparent 60%),
    radial-gradient(1px 1px at 84% 55%, rgba(200,180,255,.7), transparent 60%),
    radial-gradient(1.4px 1.4px at 25% 78%, rgba(255,255,255,.6), transparent 60%);
  background-size:220% 220%;
  animation:parallax-drift 26s ease-in-out infinite}
@keyframes parallax-drift{
  0%{transform:translate(0,0)}
  50%{transform:translate(-2.4%,-1.6%)}
  100%{transform:translate(0,0)}
}

/* L1 별가루 — js/motion.js 의 MLS.dust() 가 채운다 */
.dust{position:absolute;inset:0;pointer-events:none;overflow:hidden}
.dust i{position:absolute;width:3px;height:3px;border-radius:50%;background:#FFE9B0;
  box-shadow:0 0 6px 2px rgba(255,216,135,.7);opacity:0;animation:rise linear infinite}
@keyframes rise{0%{opacity:0;transform:translateY(0) scale(.6)}
  15%{opacity:.9}70%{opacity:.7}100%{opacity:0;transform:translateY(-130px) scale(1.1)}}

/* 월드 위 상단 바 */
.topbar{position:absolute;left:0;right:0;top:0;z-index:6;display:flex;align-items:center;gap:8px;
  padding:8px var(--gut)}
.topbar h1{font-size:var(--fs-17);font-weight:800;text-shadow:0 2px 8px rgba(0,0,0,.75)}
.topbar .rt{margin-left:auto;min-width:0;max-width:46%;white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis;font-size:var(--fs-12);color:#D8CFF5;text-shadow:0 2px 6px rgba(0,0,0,.75)}
.topbar h1{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* 판·버튼을 월드 아래에 겹쳐 놓는 자리 */
.panelwrap{position:relative;z-index:2;margin:-44px var(--gut) 0}
.btnrow{margin:10px var(--gut) 0}

/* L6 진입 스태거.
   ⚠ 절대배치 + translate(-50%,…) 로 중앙 잡은 요소에 transform 애니를 쓰면
     중앙정렬이 덮여 모서리 기준으로 찍힌다. 그런 요소는 opacity 만 쓰는 .fadein 을 쓴다. */
.stg{opacity:0;transform:translateY(14px);animation:stg .5s var(--ease-out) forwards}
@keyframes stg{to{opacity:1;transform:none}}
.fadein{opacity:0;animation:fadein .5s var(--ease-out) forwards}
@keyframes fadein{to{opacity:1}}

/* 오브젝트 공통 호흡 */
.bob{animation:bob 4.4s ease-in-out infinite}
@keyframes bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-5px)}}

/* ── 게임 UI 판 (brief §5-A) ────────────────
   하단 정보창·버튼은 CSS 도형이 아니라 생성 아트 판이다.
   border-image 로 9-슬라이스해 모서리 장식은 그대로 두고 가운데만 늘린다. */
/* 액자는 세로 높이대별 3종이다. 하나를 늘려 쓰면 옆면 장식이 뭉개진다(재민 2026-08-13 지적).
   ⚠ border-image-repeat 의 두 번째 값(세로축)은 반드시 round — stretch 로 두면
      옆면 보석·넝쿨이 세로로 늘어나 깨진다. round 는 정수 배로 반복해 원형을 지킨다.
   고르는 법: 내용 높이 ~80px=s / ~110px=m / 그 이상=l */
.gpanel{
  position:relative; color:var(--text);
  filter:drop-shadow(0 10px 22px rgba(0,0,0,.55));
  border-style:solid;
  border-width:16px 20px;
  border-image:url(img/panel-m.webp) 46 76 fill / 16px 20px stretch round;
  padding:2px 2px 4px;
}
.gpanel-s{
  border-width:13px 16px;
  border-image:url(img/panel-s.webp) 34 56 fill / 13px 16px stretch round;
}
.gpanel-l{
  border-width:34px 26px;
  border-image:url(img/panel-l.webp) 150 100 fill / 34px 26px stretch round;
  padding:4px;
}
.gbtn{
  display:flex; align-items:center; justify-content:center; gap:8px;
  width:100%; min-height:var(--btn-h-lg);
  border-style:solid; border-width:16px 30px;
  border-image:url(img/btn-plate.webp) 46 84 fill / 16px 30px stretch;
  font-weight:800; font-size:var(--fs-15); color:#3A2400;
  text-shadow:0 1px 0 rgba(255,255,255,.55);
  filter:drop-shadow(0 8px 18px rgba(242,199,92,.35));
}
.ghud{
  border-style:solid; border-width:14px 22px;
  border-image:url(img/hud-plate.webp) 40 78 fill / 14px 22px stretch;
}

/* ── 탭바 ────────────────────────────────── */
.tabbar{position:fixed;left:0;right:0;bottom:0;z-index:6;
  max-width:520px;margin:0 auto;
  display:grid;grid-template-columns:repeat(5,1fr);
  padding:6px 4px calc(6px + env(safe-area-inset-bottom));
  background:rgba(20,16,51,.92);border-top:1px solid var(--line);backdrop-filter:blur(12px)}
.tab{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
  min-height:var(--tap-min);font-size:11px;color:var(--text-dim);font-weight:600}
.tab svg{width:22px;height:22px}
.tab[aria-current="page"]{color:var(--gold-400)}
.tab[aria-current="page"] svg{filter:drop-shadow(0 0 6px rgba(242,199,92,.6))}

/* ── 배지·태그 ───────────────────────────── */
.tag{display:inline-flex;align-items:center;gap:4px;padding:3px 9px;border-radius:var(--r-pill);
  font-size:var(--fs-12);font-weight:700;background:var(--accent-soft);color:var(--violet-200)}
.tag.gold{background:rgba(242,199,92,.18);color:var(--gold-400)}
.tag.ok{background:rgba(46,158,107,.22);color:#7BE0B0}
.tag.warn{background:rgba(240,168,30,.18);color:var(--amber-500)}

/* ── 리본 타이틀(장식) ───────────────────────
   ⚠ 규칙: 리본은 장식이고 긴 글자는 리본 밖에 둔다(brief §7-5) */
.ribbon{position:relative;display:inline-block;padding:8px 22px;border-radius:var(--r-12);
  font-size:var(--fs-17);font-weight:800;color:var(--gold-400);
  background:linear-gradient(180deg,#3A2E77,#2A2058);
  border:1px solid rgba(242,199,92,.45);
  box-shadow:0 4px 14px rgba(0,0,0,.35), inset 0 1px 0 rgba(255,255,255,.18)}

/* ── 음소거 토글 (js/sound.js 가 [aria-pressed] 를 관리) ─────
   기본은 켜짐(소리 남). 눌러서 끄면 스피커에 사선이 그어진다. */
[data-sound-toggle]{position:relative}
[data-sound-toggle] .off-line{display:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round}
[data-sound-toggle][aria-pressed="false"] .off-line{display:block}
[data-sound-toggle][aria-pressed="false"] .wave{opacity:.25}

/* ── 상단 바(하위 화면) ───────────────────── */
.top{display:flex;align-items:center;gap:var(--sp-2);padding:var(--sp-2) var(--gut);
  position:sticky;top:0;z-index:4;background:linear-gradient(180deg,rgba(20,16,51,.96),rgba(20,16,51,0))}
.top h1{font-size:var(--fs-17);font-weight:700}

/* ── 펫 ──────────────────────────────────── */
.petimg{transform-origin:50% 100%;animation:breathe 3.4s ease-in-out infinite}
@keyframes breathe{0%,100%{transform:scaleY(1) scaleX(1)}50%{transform:scaleY(1.012) scaleX(.996)}}
.bubble{position:relative;background:#fff;color:#241E3A;border-radius:14px;
  padding:8px 12px;font-size:var(--fs-13);font-weight:600;box-shadow:0 6px 18px rgba(0,0,0,.35)}
.bubble::after{content:"";position:absolute;left:24px;bottom:-7px;width:0;height:0;
  border:8px solid transparent;border-top-color:#fff;border-bottom:0}
