/* ============================================================================
   villain.css — 「오늘의 빌런」 독립 랜딩 페이지
   ----------------------------------------------------------------------------
   이 페이지는 채용 사이트 안의 섹션이 아니라 **광고를 따로 돌리는 독립 페이지**다.
   그래서 히어로 영상·GSAP·핀이 없고, 첫 화면에서 바로 무엇을 하는 건지 읽힌다.

   ★ 2026-08 개편 (디자인 정본: Villain Landing.dc.html)
     랜딩이 '규칙을 읽는 화면' 에서 '사람을 고르는 화면' 으로 바뀌었다.
       왼쪽 한 문장 + 오른쪽 인물 컷 → 아래 에피소드 열 줄.
     그리고 페이지 전체가 **다크**다. 인물 컷 열 장이 전부 어두운 회의실 사진이라
     밝은 면 위에서는 사진만 구멍처럼 뚫려 보인다.

   색·폰트·라운드·타입 스케일은 전부 base.css 의 :root 토큰을 쓴다.
   **새 색을 만들지 않는다.** DESIGN_GUIDE.md §1 규칙 그대로:
     · 오렌지(--c-accent)는 면으로 쓰지 않는다 — 점 · 이유브로우 · 수치 글자만.
       예외는 하나, 히어로의 '대화 시작하기'(.vg-btn--accent). 페이지에 딱 하나뿐인
       주행동이라 면으로 세운다. 두 개가 되는 순간 규칙이 무너진다.
     · 밝은 면(--c-invert)도 하나뿐이다 — 내 말풍선. "내가 말한 것"의 표시다.
     · 인재상 해금 카드는 --c-panel-blue (채용 사이트 인재상 밴드와 같은 푸른 기라
       "여기가 그 인재상이다"가 색으로 이어진다)

   말풍선·입력·대화 영역 스펙은 문화 챗봇(§4-15)에서 그대로 가져왔다 —
   같은 사이트에서 두 채팅 UI 가 다르게 생기면 안 된다.
   ========================================================================== */

/* --- 페이지 골격 ---------------------------------------------------------
   내비가 더 이상 fixed 가 아니라서 상단 스페이서가 없다 (base.css §05).
   좌우 여백은 페이지가 아니라 **각 블록이 자기 폭으로** 잡는다 — 랜딩은
   1120px, 플레이·결과 카드는 720px 로 폭이 다르기 때문이다. */

.vg-page {
  min-height: 100svh;
  background: var(--c-page);
  padding: 0 var(--pad-x) 96px;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.vg-card {
  width: 100%;
  max-width: 720px;
  background: var(--c-surface);
  border: 1px solid var(--c-line);
  border-radius: var(--r-lg);
  padding: 32px;
}

.vg-card + .vg-card { margin-top: 20px; }

.vg-eyebrow {
  font-family: var(--font-en);
  font-weight: 700;
  font-size: var(--fs-xs);
  letter-spacing: 0.08em;
  color: var(--c-accent);
  margin: 0 0 10px;
}

.vg-screen[hidden] { display: none; }

/* 플레이·결과는 카드가 곧 화면이라 위쪽 숨이 필요하다. 랜딩은 자기 패딩을 쓴다. */
#vgPlay, #vgResult { margin-top: 56px; }

/* --- 진입 리빌 (0.6.0 · getlayers §3-2) ----------------------------------
   랜딩이 열릴 때 히어로 한 덩어리와 에피소드 열 줄이 차례로 올라온다.
   **최초 1회뿐이다** — 목록에서 다른 화를 고를 때마다 열 줄이 다시 흔들리면
   그건 연출이 아니라 잡음이다(js 가 첫 렌더에만 클래스를 건다).
   ★ transition 이 아니라 animation 이다. 두 단계(숨김 클래스 → 보임 클래스)로
     만들면 그 사이에서 스크립트가 죽었을 때 페이지가 통째로 안 보인 채 남는다.
     animation ... both 는 스스로 시작해서 스스로 끝난다.
   ★ 지연은 --i(몇 번째인가) × --stagger 다. 값 하나만 바꾸면 리듬이 바뀐다. */
@keyframes vg-rise {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

.vg-reveal {
  animation: vg-rise 0.5s var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * var(--stagger, 60ms));
}

/* --- 업데이트 공지 배너 (0.7.0) -------------------------------------------
   내비 바로 아래, <main> 위. 고정(sticky/fixed)이 아니라 문서 흐름 안이다 —
   이 페이지의 내비도 fixed 를 버렸는데(base.css §05) 배너만 고정하면 다시
   같은 문제(인물 컷이 지나가며 띠가 얼룩처럼 보이는 것)가 생긴다.
   슬림하게 — 오렌지 점 하나 · 한 줄 문구 · '자세히 →' · 닫기 × 넷뿐이다.
   오렌지는 여기서도 '면'이 아니라 '점'으로만 쓴다(파일 머리말 §1 규칙). */
.vg-update-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  max-width: var(--w-page);
  margin: 12px auto 0;
  padding: 10px var(--pad-x);
  background: var(--c-surface);
  border-top: 1px solid var(--c-line);
  border-bottom: 1px solid var(--c-line);
}
.vg-update-banner[hidden] { display: none; }

/* 판이 시작되면(대화·결과 화면) 배너를 접는다 (2026-08-15).
   공지는 랜딩에서 고를 때 읽는 것이지, 대화 중에 화면 맨 위를 차지할 것이
   아니다 — 대화 로그는 위에서부터 읽는 화면이라 그 자리가 제일 비싸다.
   ★ hidden 속성이 아니라 화면 상태로 끈다. hidden 은 updates-banner.js 의
     것이고(본 버전인가 · × 를 눌렀나), 여기서 같이 만지면 두 주인이 한 값을
     두고 싸운다 — 목록으로 돌아왔을 때 "원래 보이던 배너"를 되살릴 근거가
     사라진다. body[data-vg-screen] 은 js/villain.js 의 show() 가 찍는다. */
body[data-vg-screen="play"] .vg-update-banner,
body[data-vg-screen="result"] .vg-update-banner { display: none; }

.vg-update-banner__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--c-accent);
  flex: none;
}

.vg-update-banner__text {
  flex: 1 1 auto;
  min-width: 0;
  font-size: var(--fs-xs);
  color: var(--c-ink-soft);
  /* 한 줄로 버티다가 정말 안 되면 자연스럽게 줄바꿈한다 — 말줄임표로
     자르면 375px 에서 무슨 소식인지 못 읽고 '자세히' 를 눌러야 한다. */
  overflow-wrap: break-word;
}

.vg-update-banner__link {
  flex: none;
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--c-accent-soft);
  white-space: nowrap;
}
.vg-update-banner__link:hover { color: var(--c-accent); }

.vg-update-banner__close {
  flex: none;
  width: 24px;
  height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  font-size: 16px;
  line-height: 1;
  color: var(--c-mute);
  cursor: pointer;
}
.vg-update-banner__close:hover { color: var(--c-ink); background: var(--c-panel); }

@media (max-width: 809.98px) {
  .vg-update-banner {
    padding: 9px var(--pad-x);
    gap: 8px;
  }
  .vg-update-banner__text { font-size: 12px; }
  .vg-update-banner__link { font-size: 12px; }
}

/* --- 내비 TODAY 조회수 칩 (0.7.0) -----------------------------------------
   내비(.nav__inner)는 base.css 에서 justify-content: space-between 인 2슬롯이다.
   여기에 셋째 칸을 그냥 넣으면 칩이 정가운데로 날아간다. margin-left: auto 가
   남는 폭을 전부 먹어 space-between 이 나눌 것을 없애 버리므로, 문패는 왼쪽에
   그대로 두고 칩과 채용 CTA 만 오른쪽에 붙는다 — 마크업에 래퍼 <div> 를 하나 더
   두지 않으려고 이 방법을 골랐다(내비 구조는 채용 사이트와 같아야 한다).
   ★ 면을 주지 않는다. 오렌지도 쓰지 않는다 — 이 페이지에서 색이 칠해진 것은
     '대화 시작하기' 하나뿐이고(파일 머리말 §1), 조회수는 그 옆에서 조용히 있는
     메타 정보다. 라벨은 --c-mute, 숫자만 한 단 밝게 해서 눈이 숫자에 간다.
   ★ [hidden] 이 이기게 display 를 따로 꺼 준다 — display: inline-flex 를 준
     순간 hidden 속성만으로는 안 숨는다. 이 칩은 '숫자를 못 받으면 사라지는' 게
     기본 동작이라 이 한 줄이 기능이다.
   ⚠️ 이름이 .vg-today 가 아닌 이유 — 그 이름은 아래 '오늘의 나' 특성 카드가
     이미 갖고 있고, js/villain.js 가 querySelector('.vg-today') 로 그 카드를
     잡아 진입 리빌을 건다. 내비의 칩이 문서에서 먼저 나오므로 같은 이름을
     쓰면 리빌이 엉뚱한 데 걸리고 특성 카드는 조용히 안 움직인다. */
.vg-visits {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  margin-left: auto;
  padding: 6px 10px;
  border: 1px solid var(--c-line-soft);
  border-radius: var(--r-full);
  white-space: nowrap;
  flex: none;
}
.vg-visits[hidden] { display: none; }

.vg-visits__label {
  font-family: var(--font-en);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--c-mute);
}

.vg-visits__num {
  font-family: var(--font-en);
  font-size: var(--fs-2xs);
  font-weight: 700;
  font-variant-numeric: tabular-nums;   /* 숫자가 올라도 칩 폭이 덜컹거리지 않게 */
  color: var(--c-ink-soft);
}

/* 375px 에서 문패·칩·채용 CTA 셋이 한 줄에 들어가야 한다. 칩이 CTA 를 밀어내면
   이 페이지의 유일한 전환 링크가 줄바꿈되므로, 좁아질수록 칩부터 줄인다. */
@media (max-width: 809.98px) {
  .vg-visits { padding: 5px 8px; gap: 5px; }
  .vg-visits__label { font-size: 10px; letter-spacing: 0.06em; }
  .vg-visits__num { font-size: 12px; }
}
/* 375px 까지는 라벨 'TODAY' 가 그대로 붙어 있어도 채용 CTA 가 안 밀린다(실측:
   문패 끝 121px · 칩 168–266 · CTA 282–355). 350px 근처에서 넉 픽셀이 모자라
   CTA 가 화면 밖으로 나가기 시작하므로, 그때 라벨부터 버리고 숫자만 남긴다 —
   숫자 없는 'TODAY' 는 아무 정보도 아니지만 라벨 없는 숫자는 title 로 읽힌다.
   칩을 통째로 숨기지 않는 이유는 좁은 화면에서만 사이트가 조용해 보이기 때문. */
@media (max-width: 359.98px) {
  .vg-visits { padding: 4px 8px; }
  .vg-visits__label { display: none; }
}

/* ==========================================================================
   랜딩
   ========================================================================== */

.vg-landing {
  position: relative;
  width: 100%;
  max-width: var(--w-page);
}

/* 히어로 뒤 오렌지 글로우. 이 페이지에서 오렌지를 '면'으로 쓰는 유일한 자리인데,
   경계가 없는 빛이라 면으로 읽히지 않는다. 폭이 좁아지면 화면 밖으로 넘치므로
   base.css 의 html overflow-x:clip + body overflow-x:hidden 에 기대고 있다 —
   그 줄들을 지우면 가로 스크롤·모바일 좌우 흔들림이 생긴다. */
.vg-glow {
  position: absolute;
  top: -280px;
  left: 50%;
  transform: translateX(-50%);
  width: min(900px, 130vw);
  height: 620px;
  background: radial-gradient(ellipse at center,
              rgba(244, 123, 26, 0.18), rgba(10, 9, 9, 0) 65%);
  pointer-events: none;
}

/* --- 히어로 -------------------------------------------------------------- */

.vg-hero {
  position: relative;   /* 글로우 위 */
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 56px;
  padding: 56px 0 96px;
}

.vg-hero__copy {
  flex: 1 1 420px;
  min-width: 300px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 24px;
}

/* 폭에 따라 36 → 58px. 타입 스케일 토큰(--fs-h1)을 쓰지 않는 유일한 글자다 —
   이 한 문장만 광고 헤드라인 크기로 서야 한다. */
.vg-hero__title {
  margin: 0;
  font-size: clamp(30px, 5.4vw, 58px);
  line-height: 1.14;
  font-weight: 800;
  letter-spacing: -0.035em;
  color: var(--c-ink);
  text-wrap: balance;
}
.vg-hero__title em { font-style: normal; color: var(--c-accent); }

.vg-hero__lead {
  margin: 0;
  max-width: 32em;
  font-size: var(--fs-body);
  line-height: 1.7;
  font-weight: 500;
  color: var(--c-body);
  text-wrap: pretty;
}

.vg-hero__copy .vg-actions { margin-top: 8px; }

.vg-hero__meta {
  margin: 0;
  font-size: var(--fs-2xs);
  color: var(--c-mute);
}

/* 잠긴 화를 ?p= 링크로 열었을 때만 뜬다. 시작 버튼 바로 아래에 붙어서 왜 못
   누르는지와 어디로 가면 되는지를 그 자리에서 말한다 — 잠긴 버튼만 남으면
   고장으로 읽힌다. 경고색을 쓰지 않는다: 잘못 온 게 아니라 아직 안 연 것이다. */
.vg-locknote {
  margin: 0;
  font-size: var(--fs-2xs);
  line-height: var(--lh-body);
  color: var(--c-body);
}
.vg-locknote[hidden] { display: none; }

/* --- 히어로 오른쪽 단 -----------------------------------------------------
   2026-08-22 개편: 여기 서 있던 '고른 에피소드 카드' 는 에피소드 목록 위
   (.vg-eps__stage)로 내려갔고, 이 자리에는 히어로에 걸린 기능의 그림이 선다.
   폭·최소폭은 그대로다 — 오른쪽 면의 무게가 바뀌면 첫 화면이 흔들린다. */

.vg-hero__art {
  flex: 0 1 400px;
  min-width: 280px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

/* --- 새 기능 뱃지 ---------------------------------------------------------
   히어로에 걸린 것이 '방금 생긴 기능' 이라고 말하는 한 줄. 오렌지를 면으로 쓰지
   않는 규칙(맨 위 §팔레트)에 맞춰 점 하나와 글자만 오렌지다. */
.vg-hero__badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: var(--fs-2xs);
  font-weight: 700;
  color: var(--c-accent-soft);
}

.vg-hero__badge-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--c-accent);
  box-shadow: 0 0 0 4px rgba(244, 123, 26, 0.14);
}

/* --- 소환진 컷 ------------------------------------------------------------
   인물 컷(.vg-feature)과 같은 4:5 · 같은 모서리 · 같은 그림자다. 히어로에 무엇이
   걸리든 오른쪽 면이 같은 크기로 서야 랜딩의 균형이 유지된다. */
.vg-summon-art {
  position: relative;
  margin: 0;
  border-radius: var(--r-xl);
  overflow: hidden;
  border: 1px solid var(--c-line-soft);
  background: var(--c-panel-alt);
  aspect-ratio: 4 / 5;
  box-shadow: 0 32px 80px rgba(0, 0, 0, 0.55);
}

.vg-summon-art__img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* 캡션 두 줄이 사진 위에 얹히므로 아래쪽을 덮어 준다(인물 컷과 같은 방식) */
.vg-summon-art__veil {
  position: absolute;
  inset: auto 0 0 0;
  height: 52%;
  background: linear-gradient(to top, rgba(10, 9, 9, 0.94), rgba(10, 9, 9, 0));
  pointer-events: none;
}

.vg-summon-art__cap {
  position: absolute;
  inset: auto 0 0 0;
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  pointer-events: none;
}

.vg-summon-art__tag {
  font-family: var(--font-en);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.14em;
  /* 12px 오렌지는 순정 --c-accent 로는 어둡다(인물 컷 EP 번호와 같은 톤) */
  color: var(--c-accent-soft);
}

.vg-summon-art__line {
  font-size: var(--fs-xs);
  font-weight: 500;
  color: var(--c-mute);
}

.vg-feature {
  position: relative;
  border-radius: var(--r-xl);
  overflow: hidden;
  border: 1px solid var(--c-line-soft);
  background: var(--c-panel-alt);
  aspect-ratio: 4 / 5;
  box-shadow: 0 32px 80px rgba(0, 0, 0, 0.55);
}

.vg-feature__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: opacity 0.25s ease;
}
/* 사진을 갈아 끼우는 동안만 비운다 (js/villain.js swapFeature) */
.vg-feature__img[data-loading='true'] { opacity: 0.35; }

/* 캡션이 사진 위에 얹히므로 아래쪽을 덮어 준다. 글자에 그림자를 주는 대신
   면을 깔아야 어떤 사진이 와도 대비가 보장된다. */
.vg-feature__veil {
  position: absolute;
  inset: auto 0 0 0;
  height: 58%;
  background: linear-gradient(to top, rgba(10, 9, 9, 0.94), rgba(10, 9, 9, 0));
  pointer-events: none;
}

.vg-feature__cap {
  position: absolute;
  inset: auto 0 0 0;
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  pointer-events: none;
}

.vg-feature__ep {
  font-family: var(--font-en);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.14em;
  /* 12px 오렌지는 순정 --c-accent 로는 어둡다. 작은 글자 전용 톤을 쓴다. */
  color: var(--c-accent-soft);
}

.vg-feature__way {
  font-size: var(--fs-team-name);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--c-ink);
}

.vg-feature__who {
  font-size: var(--fs-xs);
  font-weight: 500;
  color: var(--c-mute);
}

/* 과제 한 줄 — 카드 밖에 둔다. 사진 위에 얹으면 미션이 분위기에 먹힌다. */
.vg-task {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 16px 18px;
  border-radius: var(--r-lg);
  background: rgba(254, 254, 254, 0.04);
  border: 1px solid var(--c-line-soft);
}

.vg-task__label {
  flex: 0 0 auto;
  font-size: var(--fs-2xs);
  font-weight: 700;
  color: var(--c-accent);
}

.vg-task__text {
  font-size: var(--fs-sm);
  line-height: 1.6;
  font-weight: 500;
  color: var(--c-ink-soft);
}

/* --- 지금 고른 에피소드 (목록 위) -----------------------------------------
   2026-08-22 에 히어로에서 통째로 내려온 한 벌이다 — 사진 한 단, 과제·시작
   버튼 한 단. 목록 바로 위라 '고른 줄' 과 '시작' 이 같은 화면에 남는다. */
.vg-eps__stage {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 32px;
  margin-bottom: 36px;
}

.vg-eps__stage .vg-feature {
  flex: 0 1 300px;
  min-width: 240px;
}

.vg-eps__go {
  flex: 1 1 340px;
  min-width: 280px;
  /* 넓은 화면에서 과제 한 줄이 1000px 짜리 상자로 늘어나면 읽는 폭이 무너진다 */
  max-width: 560px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 16px;
}

/* 과제 상자는 단 폭을 다 쓴다 — 글자 수에 따라 폭이 들쭉날쭉하면 목록 위가 지저분하다 */
.vg-eps__go .vg-task { align-self: stretch; }
/* .vg-actions 의 기본 위 숨(28px)은 히어로용이다. 여기서는 gap 이 이미 있다 */
.vg-eps__go .vg-actions { margin-top: 0; }

/* --- 에피소드 목록 -------------------------------------------------------
   칩 스트립(.vg-chip)을 걷어내고 열 줄짜리 목차로 바꿨다. 칩에는 이름만 있어서
   무엇을 하는 판인지 고를 근거가 없었다. 지금은 인재상·인물·과제·난이도가 한 줄에
   다 있다. 넓은 화면에서는 2열로 접힌다(열 줄을 세로로 세우면 스크롤이 길다). */

/* --- 오늘의 나 (0.6.0) ----------------------------------------------------
   판마다 붙는 버프/패널티 하나. 히어로와 에피소드 목록 **사이**에 얇게 눕힌다 —
   시작 버튼과 같은 화면에 있어야 "이 조건으로 들어간다"가 읽히고, 그렇다고 히어로
   안에 넣으면 첫 화면의 주행동(시작 버튼)과 눈이 갈린다.
   ★ 버프는 오렌지 글자, 패널티는 --c-mute 다. 붉은색을 쓰지 않는다(팔레트에 없고,
     패널티는 벌이 아니라 오늘의 조건이다 — 실패 표시와 같은 태도). */
.vg-today {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
  margin-bottom: 40px;
  padding: 16px 20px;
  border: 1px solid var(--c-line);
  /* 랜딩의 다른 상자(.vg-task · .vg-card)가 전부 --r-lg 다. 여기만 --r-md 라
     같은 화면에서 모서리가 두 종류로 보였다 (0.6.0 디자인 점검). */
  border-radius: var(--r-lg);
  background: var(--c-surface);
}

.vg-today__main { min-width: 0; display: flex; flex-direction: column; gap: 4px; }

.vg-today__label {
  font-size: var(--fs-2xs);
  font-weight: 600;
  color: var(--c-dim);
}

.vg-today__head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }

.vg-today__name {
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--c-ink);
}
/* --c-accent-soft 는 '오렌지 글자가 12–13px 로 작아질 때만' 쓰는 톤이다
   (base.css §01). 이 이름은 16px 라 순정 --c-accent 자리다 — 0.6.0 디자인 점검에서
   되돌렸다. 12px 짜리 .vg-ep__done · .vg-feature__ep 는 soft 가 맞다. */
.vg-today__name[data-type='buff'] { color: var(--c-accent); }
.vg-today__name[data-type='penalty'] { color: var(--c-mute); }

.vg-today__type {
  font-size: var(--fs-2xs);
  font-weight: 600;
  color: var(--c-body);
  border: 1px solid var(--c-line);
  border-radius: var(--r-full);
  padding: 1px 8px;
}
.vg-today__type[hidden] { display: none; }

.vg-today__desc {
  font-size: var(--fs-2xs);
  line-height: var(--lh-body);
  color: var(--c-body);
  text-wrap: pretty;
}

/* --- 명예 특성 줄 (0.10.0) ------------------------------------------------
   '오늘의 나' 카드 안, 설명 바로 아래에 눕는다. 뽑기 결과(특성)와 지나온 자리의
   이름(명예 특성)은 같은 카드에서 위아래로 갈린다 — 새 카드를 만들면 랜딩에
   상자가 셋이 되고 목록이 화면 밖으로 밀린다.
   ★ 면은 --c-panel-blue(인재상 해금·보스전과 같은 푸른 기)에 1px 헤어라인,
     오렌지는 글자에만. 이모지는 쓰지 않는다. */
.vg-honors {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  margin-top: 2px;
}
.vg-honors[hidden] { display: none; }

.vg-honors__label {
  font-size: var(--fs-2xs);
  font-weight: 600;
  color: var(--c-dim);
}

.vg-honors__badge {
  font-size: var(--fs-2xs);
  font-weight: 700;
  color: var(--c-ink);
  background: var(--c-panel-blue);
  border: 1px solid var(--c-line);
  border-radius: var(--r-full);
  padding: 2px 10px;
}

/* 명대사만 글자를 오렌지로 세운다 — 셋과 다른 종류의 것이고(쓰면 사라진다)
   보스전에서만 쓰는 한 번이라 같은 무게로 두면 그 사실이 안 읽힌다. */
.vg-honors__badge--quote { color: var(--c-accent); }

/* 라벨이 값표라서 길어진다('퀴즈 풀고 다시 뽑기'). 줄바꿈만 막고 크기를 조인다. */
.vg-today__reroll {
  flex: 0 0 auto;
  padding: 10px 18px;
  font-size: var(--fs-xs);
  white-space: nowrap;
}

/* 손잡이 둘이 한 줄에 선다(0.18.0 — '다시 뽑기' · '내 설득 스타일'). 카드가
   space-between 이라 이 묶음이 오른쪽 끝을 잡는다. */
.vg-today__acts {
  flex: 0 0 auto;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.vg-eps { position: relative; padding-bottom: 88px; }

.vg-eps__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding-bottom: 20px;
  border-bottom: 1px solid var(--c-line);
}

.vg-eps__title {
  margin: 0;
  font-size: var(--fs-md);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--c-ink);
}

.vg-eps__meta {
  display: flex;
  align-items: baseline;
  gap: 14px;
}

.vg-eps__count {
  font-family: var(--font-en);
  font-size: var(--fs-2xs);
  font-weight: 700;
  color: var(--c-dim);
}

/* 기록 지우기 — 목록 제목 줄에 붙는 부가 손잡이다. 눌러야 할 버튼(에피소드)보다
   눈에 덜 띄어야 해서 글자 링크 모양 그대로, 색만 한 단 낮춘다. */
/* 두 클래스를 함께 적는다 — .vg-textlink 가 이 파일에서 아래쪽에 있어서, 한 클래스로
   쓰면 글자 크기·색·여백을 그쪽이 도로 가져간다(같은 특이도면 뒤가 이긴다). */
.vg-eps__reset.vg-textlink {
  font-size: var(--fs-2xs);
  color: var(--c-dim);
  /* 글자 높이가 15px 라 손가락으로는 겨우 닿는다. 위아래로 여백을 줘 누를 자리를
     넓힌다 — baseline 정렬이라 여백을 줘도 '10 EPISODES' 와 줄이 어긋나지 않는다.
     줄바꿈은 막는다: 좁은 화면에서 '기록 / 지우기' 로 접히면 제목 줄이 두 줄이 된다. */
  padding: 6px 0;
  white-space: nowrap;
}
.vg-eps__reset[hidden] { display: none; }

/* 계정 연동 (0.15.0) — 로그인 손잡이와 상태 한 줄. '기록 지우기' 와 같은 급의
   부가 손잡이라 같은 낮춤(크기·색·여백)을 그대로 쓴다. */
.vg-eps__login.vg-textlink {
  font-size: var(--fs-2xs);
  color: var(--c-dim);
  padding: 6px 0;
  white-space: nowrap;
}
.vg-eps__login[hidden] { display: none; }
.vg-eps__sync {
  font-size: var(--fs-2xs);
  color: var(--c-dim);
}
.vg-eps__sync[hidden] { display: none; }

/* 1120px 에서 정확히 2열이 되는 값이다(2×460+40 ≤ 1120 < 3×460+80).
   3열까지 들어가긴 하는데, 그러면 한 칸이 340px 로 좁아져서 인물 줄과 과제 줄이
   각각 두 줄로 접힌다 — 목록이 아니라 카드 더미가 된다. */
.vg-eps__list {
  /* 열 줄이 차례로 올라오는 간격. 히어로(60ms)보다 촘촘하다 — 줄이 열이라
     같은 간격이면 마지막 줄이 반 초 뒤에 도착한다. */
  --stagger: 42ms;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(460px, 1fr));
  gap: 0 40px;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* ★ 호버는 --lift 변수 하나로만 굴린다 (0.6.0 · getlayers §2-1).
   js/villain.js 가 rAF + lerp 로 0→1 을 굴리고, 여기 있는 네 가지 효과
   (행 바닥 · 썸네일 색 · 썸네일 크기 · 오른쪽 화살표)가 전부 그 한 값에서
   calc() 로 파생된다. 속성마다 transition 을 걸지 않는 게 핵심이다 — 걸면
   네 효과가 각자의 곡선으로 움직여서 한 덩어리로 안 읽힌다.
   잠긴 행은 js 가 아예 묶지 않고, 아래에서 값도 0 으로 못 박는다. */
.vg-ep {
  --lift: 0;
  position: relative;
  width: 100%;
  display: grid;
  grid-template-columns: 26px 46px 1fr auto;
  align-items: center;
  /* 14 → 12px. 오른쪽에 화살표 길(18px)을 내면서 글자 칸이 그만큼 줄었다.
     칸 하나가 20px 도 남지 않는 목록이라(2열 · 460px) 여기서 도로 벌어 온다 —
     한 줄이 두 줄로 접히면 그때부터 목록이 아니라 카드 더미가 된다. */
  gap: 12px;
  padding: 14px 22px 14px 8px;
  border: 0;
  border-bottom: 1px solid var(--c-line-soft);
  background: rgba(254, 254, 254, calc(var(--lift, 0) * 0.05));
  color: var(--c-ink);
  text-align: left;
  cursor: pointer;
}

/* 대각선이 아니라 오른쪽 화살표다 — 이 페이지의 화살표 글리프는 한글 폰트에
   없어서 Manrope 로 그리는데(base.css §04), 그 폰트에 있는 것이 '→' 다.
   ★ 흐름에서 빼 둔다(absolute). 격자 칸으로 두면 열 줄의 글자 칸이 통째로 줄어
     인물 줄이 두 줄로 접힌다 — 호버 장식 하나가 목록의 밀도를 바꾸면 안 된다.
   ★ 오른쪽 끝에 붙여 놓고 폭만 키운다. overflow:hidden 이 왼쪽을 잘라서
     화살표가 오른쪽에서 밀려 들어오는 것처럼 보인다(getlayers §2-1 의 콤보). */
.vg-ep::after {
  content: '→';
  position: absolute;
  right: 4px;
  top: 50%;
  width: calc(var(--lift, 0) * 14px);
  opacity: var(--lift, 0);
  overflow: hidden;
  transform: translateY(-50%);
  text-align: right;
  white-space: nowrap;
  font-family: var(--font-en);
  font-size: 13px;
  font-weight: 800;
  line-height: 1;
  color: var(--c-accent);
  pointer-events: none;
}

/* 지금 고른 줄. 면을 깔지 않고 번호만 오렌지로 세운다 — 목록이 열 줄이라
   면으로 표시하면 그 줄만 버튼처럼 튀어나온다. */
.vg-ep[aria-current='true'] .vg-ep__no { color: var(--c-accent); }

.vg-ep__no {
  font-family: var(--font-en);
  font-size: var(--fs-2xs);
  font-weight: 800;
  color: var(--c-dim);
}

.vg-ep__thumb {
  width: 46px;
  height: 56px;
  border-radius: var(--r-sm);
  background-color: var(--c-panel-alt);
  /* cover 로 두면 인물 컷(4:5)이 46×56 에 통째로 들어가 얼굴이 점만 해진다 —
     열 줄이 전부 어두운 회의실 조각으로 보인다. 두 배로 키워 얼굴 높이(원본의
     30% 언저리)를 잡는다. 열 장 모두 상반신이 같은 자리에 있어서 한 값으로 된다. */
  background-size: 200% auto;
  background-position: 50% 30%;
  /* 살짝 빼 두고 hover 에서 되돌린다. 열 장이 한꺼번에 쨍하면 목록이 아니라
     갤러리가 된다. ★ 되돌리는 일도 --lift 가 한다(위) — 색과 크기가 한 값에서
     나와야 사진이 '깨어나는' 하나의 동작으로 읽힌다. */
  filter: grayscale(calc(0.35 - var(--lift, 0) * 0.35));
  transform: scale(calc(1 + var(--lift, 0) * 0.05));
}
.vg-ep[aria-current='true'] .vg-ep__thumb { filter: none; }

.vg-ep__main { display: flex; flex-direction: column; gap: 6px; min-width: 0; }

.vg-ep__head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }

.vg-ep__way {
  font-size: var(--fs-sm);
  font-weight: 700;
  letter-spacing: -0.02em;
}

/* 장면 칩 (0.6.0) — 이 화의 무대. 화마다 다르다(회의실 · 점심 · 퇴근길 …).
   인재상 이름 바로 뒤에 아주 작게 붙인다: 고를 때 "어디서 만나는가"가 한 줄 안에
   보여야 하는데, 크게 두면 인재상 이름과 무게가 같아져 줄이 두 덩어리로 읽힌다.
   좁은 화면에서는 낱말을 떼고 이모지만 남긴다(아래 반응형) — 줄이 접히는 것보다
   낫다. 그래서 이모지와 낱말이 각각 span 이다.
   ★ 0.6.0 디자인 점검: 낱말만 회색으로 적어 두니 바로 뒤의 인물 줄(.vg-ep__who)과
     크기·색·굵기가 똑같아서 한 줄이 통째로 회색 덩어리로 읽혔다. 칩이라고 부르는
     것을 칩으로 보이게 한다 — 테두리 필 한 겹. 값은 '오늘의 나'의 버프/패널티
     배지(.vg-today__type)와 같은 것을 쓴다(이 페이지의 칩 문법은 하나여야 한다). */
.vg-ep__scene {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  /* 테두리 없이 바닥만 깐다. 이 줄에 쓸 수 있는 여백이 20px 남짓이라
     (2열 목록 · README §2) 필 하나에 테두리까지 두르면 인물 줄이 접힌다. */
  padding: 1px 6px;
  border-radius: var(--r-full);
  background: rgba(254, 254, 254, 0.055);
  font-size: var(--fs-2xs);
  font-weight: 500;
  color: var(--c-body);
  white-space: nowrap;
}

.vg-ep__who,
.vg-ep__goal {
  font-size: var(--fs-2xs);
  font-weight: 500;
  color: var(--c-mute);
}
.vg-ep__goal { line-height: 1.5; text-wrap: pretty; }

/* 줄 하나에 붙는 조건 안내(0.10.0 — 보스 줄의 명예 특성 개수). 과제 줄보다 한 단
   아래 무게로 둔다: 이건 이 판의 내용이 아니라 이 판에 들고 들어가는 것이다. */
.vg-ep__note {
  font-size: var(--fs-2xs);
  font-weight: 600;
  color: var(--c-dim);
  line-height: 1.5;
}

/* 이 화를 깨면 남는 것(0.13.1). 과제 줄(.vg-ep__goal)과 같은 크기지만 색을 한 단
   올린다 — 이건 지금 판의 내용이 아니라 판이 끝난 뒤에 손에 쥐는 것이라서, 목록을
   훑는 눈에 먼저 걸려야 다음 화를 고를 이유가 된다. 오렌지는 글자만이다. */
.vg-ep__note--reward { color: var(--c-accent-soft); }

/* 한 번이라도 끝낸 화. 도감의 씨앗이라 눈에 띄되 자랑은 아닌 무게로 둔다. */
.vg-ep__done {
  font-size: var(--fs-2xs);
  font-weight: 700;
  color: var(--c-accent-soft);
}

/* 못 깬 화. 붉은색을 쓰지 않는다 — 팔레트에 없기도 하고, 실패를 태워 놓으면
   목록이 성적표로 읽힌다. 오렌지에서 한 단 내려 사실만 남긴다. */
.vg-ep__done--fail { color: var(--c-mute); }

/* --- 아직 안 열린 화 -------------------------------------------------------
   앞 화를 깨거나 세 번 붙어야 열린다. 통째로 가리지 않는다 — 무엇이 기다리고
   있는지(인재상·인물·과제)는 보여야 다음 판을 할 이유가 된다. 대신 눌리지
   않는다는 것이 한눈에 보이게 밝기를 내리고 사진에서 색을 뺀다.
   ★ 자물쇠 그림 대신 글자로 조건을 적는다(.vg-ep__lock). 🔒 만 있으면 무엇을
     해야 열리는지 모른 채 목록을 노려보게 된다. */
.vg-ep--locked {
  cursor: default;
  opacity: 0.5;
}
/* 잠긴 행은 반응하지 않는다. js 가 호버를 아예 묶지 않지만(renderChapters),
   값 자체를 여기서 못 박아 둔다 — 나중에 누가 묶어도 화면은 조용하다. */
.vg-ep--locked { --lift: 0 !important; }
.vg-ep--locked .vg-ep__thumb { filter: grayscale(1); }

.vg-ep__lock {
  font-size: var(--fs-2xs);
  font-weight: 600;
  color: var(--c-body);
  white-space: nowrap;
}

/* 난이도 — 색은 .vg-ep__diff 에 한 번만 정하고 점과 글자가 currentColor 로 받는다.
   세 군데에 같은 색을 따로 쓰면 하나 고칠 때 하나가 남는다. */
.vg-ep__diff {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--c-body);
}
.vg-ep__diff[data-level='1'] { color: var(--c-ink); }
.vg-ep__diff[data-level='3'] { color: var(--c-accent); }

.vg-ep__dots { display: flex; align-items: center; gap: 3px; }

.vg-ep__dot {
  width: 5px;
  height: 5px;
  border-radius: var(--r-full);
  background: rgba(254, 254, 254, 0.14);
}
.vg-ep__dot[data-on='true'] { background: currentColor; }

/* --- 크레딧 --------------------------------------------------------------
   귓속말·행동을 사는 화폐다. 두 곳에 같은 모양으로 뜬다 — 랜딩의 글 목록 제목
   줄, 그리고 플레이 화면 상단 바(남은 턴 아래). 숫자만 오렌지다: 이 페이지에서
   오렌지는 수치 강조에만 쓴다(§1-3, 남은 턴과 같은 규칙). */
.vg-credit {
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
}

.vg-credit__num {
  font-family: var(--font-en);
  font-size: var(--fs-sm);
  font-weight: 800;
  color: var(--c-accent);
  line-height: 1;
}

.vg-credit__label {
  font-size: var(--fs-2xs);
  color: var(--c-body);
}

/* 상단 바 안에서는 남은 턴 밑에 한 줄로 붙는다. 새 줄을 만들지 않는 게 핵심이다 —
   375×812 에서 플레이 화면의 세로 여유가 4px 뿐이다(README §6). */
.vg-credit--bar {
  margin-top: 8px;
  justify-content: flex-end;
  width: 100%;
}
.vg-credit--bar .vg-credit__num { font-size: var(--fs-xs); }

/* '오늘의 나'를 크레딧 줄 뒤에 이어 붙인다 — `3 크레딧 · 😎 훈훈한 첫인상`.
   ★ 새 줄을 만들지 않는 것이 이 표시의 전부다(모바일 높이 예산 · README §2).
     글자를 크레딧 라벨과 같은 크기로 두고 색만 한 단 낮춘다. 비면 js 가 빈
     문자열을 넣고, :empty 로 여백까지 사라진다. */
.vg-credit__trait {
  font-size: var(--fs-2xs);
  color: var(--c-mute);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.vg-credit__trait:empty { display: none; }

/* --- 알고케어 이야기 (크레딧을 버는 곳) -----------------------------------
   에피소드 목록과 같은 리듬으로 둔다(같은 제목 줄, 같은 구분선). 다른 사이트로
   나가는 링크 열 개라 눈에 더 띄면 안 된다 — 이 화면의 주행동은 여전히 판을
   시작하는 것이다. 크레딧이 필요해진 사람만 여기까지 내려온다. */
.vg-posts { position: relative; padding-bottom: 80px; }

.vg-posts__lead {
  margin: 16px 0 0;
  font-size: var(--fs-2xs);
  color: var(--c-mute);
}

.vg-posts__list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(460px, 1fr));
  gap: 0 40px;
  margin: 8px 0 0;
  padding: 0;
  list-style: none;
}

.vg-post {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 8px;
  border-bottom: 1px solid var(--c-line-soft);
}

.vg-post__link {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 5px;
  color: var(--c-ink);
  text-decoration: none;
}
.vg-post__link:hover .vg-post__title { color: var(--c-accent); }

/* 태그·분량·매체 셋이 붙으면 좁은 화면에서 한 줄에 안 들어간다. 줄이 접히는 건
   괜찮지만 제목 쪽으로 밀려 붙으면 안 되니 세로 간격을 조금 준다. */
.vg-post__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; }

/* 미디엄 글 제목 앞에 붙어 있는 [영양제]·[조직문화] 를 서버가 떼어 여기로 보낸다 */
.vg-post__tag {
  font-size: var(--fs-2xs);
  font-weight: 700;
  color: var(--c-accent-soft);
}

.vg-post__min,
.vg-post__src,
.vg-post__sum {
  font-size: var(--fs-2xs);
  color: var(--c-mute);
}

/* 미디엄 밖으로 나가는 항목(뉴스·유튜브)의 매체 이름. 분량 표시보다 한 칸 뒤로
   물러나 있어야 '읽는 데 4분 ZDNet Korea' 가 한 덩어리로 읽히지 않는다. */
.vg-post__src { color: var(--c-dim); }
.vg-post__src::before { content: '· '; }
.vg-post__sum { line-height: 1.5; text-wrap: pretty; }

.vg-post__title {
  font-size: var(--fs-sm);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.4;
  transition: color 0.2s ease;
}

/* 한 줄의 상태가 전부 이 버튼에 있다: 글 열기 → N초 뒤 받기 → 크레딧 받기 →
   받음. 받을 수 있을 때만 오렌지로 선다 — 그 순간이 이 목록의 유일한 사건이다. */
.vg-post__claim {
  flex: 0 0 auto;
  min-width: 104px;
  padding: 9px 12px;
  border: 1px solid var(--c-line);
  border-radius: var(--r-full);
  background: transparent;
  color: var(--c-ink-soft);
  font-family: inherit;
  font-size: var(--fs-2xs);
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
.vg-post__claim:hover:not(:disabled) { background: var(--c-panel); }
.vg-post__claim:disabled { cursor: default; color: var(--c-dim); }

.vg-post[data-state='ready'] .vg-post__claim {
  border-color: var(--c-accent);
  color: var(--c-accent);
}
.vg-post[data-state='ready'] .vg-post__claim:hover { background: rgba(244, 123, 26, 0.08); }

/* 이미 받은 글. 목록에서 지우지 않는다 — 읽은 것이 쌓이는 게 보여야 한다. */
.vg-post[data-state='done'] { opacity: 0.55; }

/* 채용 공유 줄. 목록과 같은 리듬의 한 줄이지만 li 밖 전폭이다 — 글 목록이
   2단으로 접히는 넓은 화면에서도 항상 목록 아래 한 줄로 남는다. */
.vg-post--share { margin-top: 4px; }

.vg-ep__level {
  font-size: 12px;
  font-weight: 600;
  width: 34px;
}

/* --- 버튼 --------------------------------------------------------------- */

.vg-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  margin-top: 28px;
}

/* 기본은 '밝은 면' 이다. 다크 페이지에서 솔리드는 흰 pill 이 된다. */
.vg-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 12px 24px;
  border: 1px solid transparent;
  border-radius: var(--r-full);
  background: var(--c-invert);
  color: var(--c-invert-ink);
  font-family: var(--font-kr);
  font-size: var(--fs-sm);
  font-weight: 600;
  line-height: var(--lh-ui);
  letter-spacing: var(--ls-tight);
  cursor: pointer;
  transition: transform 0.2s ease, background 0.2s ease;
}

.vg-btn:hover { transform: translateY(-1px); background: var(--c-white); }
.vg-btn:disabled { opacity: 0.4; cursor: default; transform: none; }
/* ★ hidden 속성을 되살린다. 브라우저 기본값(display:none)은 **작성자 규칙**인 위
   display:inline-flex 에 진다 — 그래서 hidden 을 걸어도 버튼이 그대로 보였다
   (뽑기가 끝난 뒤에도 '뽑기' 버튼이 남아 있었다). 이 파일에서 hidden 을 쓰는
   요소마다 같은 짝이 필요하다(.vg-eps__reset · .vg-today__type … 도 같은 이유다). */
.vg-btn[hidden], .vg-textlink[hidden] { display: none; }

/* 오렌지 면은 이 버튼 하나뿐이다 (파일 머리말 참고). 히어로의 주행동.
   ★ 0.6.0: 이 페이지에서 마이크로 인터랙션을 붙이는 유일한 버튼이다
     (getlayers §7-1 — `--btn-hover` 한 변수에서 파생되는 인셋 글로우).
     원본은 반투명 흰 버튼 안쪽에 웜·쿨 두 광원을 심는데, 우리 것은 이미 오렌지
     면이라 광원을 밖으로 한 겹 더 내보낸다: 위쪽 하이라이트(면이 서 보인다) +
     아래쪽 안쪽 웜글로우(면에 두께가 생긴다) + 바깥 오렌지 번짐(검정 위에서만
     보이는 빛). 셋 다 --btn-hover 하나로 커진다.
     ★ 새 색을 만든 것이 아니다 — 전부 --c-accent(#F47B1A)와 흰색의 알파다.
       (토큰에 rgb 채널 변수가 없어서 여기만 숫자로 적는다. accent 를 바꾸면
        .vg-compose[data-mode="act"] 와 함께 이 세 줄도 고칠 것.) */
.vg-btn--accent {
  --btn-hover: 0;
  min-height: 56px;
  padding: 0 32px;
  background: var(--c-accent);
  color: var(--c-invert-ink);
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.01em;
  box-shadow:
    inset 0 1px 0 0 rgba(255, 255, 255, calc(0.16 + var(--btn-hover, 0) * 0.16)),
    inset 0 calc(-12px - var(--btn-hover, 0) * 8px)
          calc(20px + var(--btn-hover, 0) * 24px) -14px rgba(255, 226, 190, 0.55),
    0 calc(6px + var(--btn-hover, 0) * 6px)
      calc(16px + var(--btn-hover, 0) * 22px) -12px
      rgba(244, 123, 26, calc(0.35 + var(--btn-hover, 0) * 0.4));
}
.vg-btn--accent:hover { background: var(--c-accent-hover); }
/* 잠긴 화를 ?p= 로 열면 이 버튼이 잠긴다. 빛까지 남으면 눌리는 것처럼 보인다. */
.vg-btn:disabled { --btn-hover: 0 !important; }

.vg-btn--ghost {
  background: transparent;
  color: var(--c-ink);
  border-color: var(--c-line);
}
.vg-btn--ghost:hover { background: var(--c-panel); }

/* 눌려 있는 토글(지금은 '행동하기' 하나뿐이다). 오렌지를 면으로 깔지 않고
   글자와 테두리로만 쓴다 — 면은 히어로 CTA 하나뿐이라는 규칙을 지킨다. */
.vg-btn--ghost[aria-pressed="true"] {
  color: var(--c-accent);
  border-color: var(--c-accent);
}
.vg-btn--ghost[aria-pressed="true"]:hover { background: rgba(244, 123, 26, 0.08); }

/* 크레딧이 모자란 도구 버튼. **잠그지 않는다** — 잠그면 눌러 볼 수가 없어서
   "왜 안 되는지"와 "어디서 버는지"를 말해 줄 자리가 사라진다(누르면 로그 안에
   글 한 편이 열린다). 눌리긴 하되 지금은 살 수 없다는 것만 밝기로 알린다. */
.vg-btn[data-need='true'] {
  opacity: 0.55;
  border-style: dashed;
}

.vg-btn__icon { width: 17px; height: 17px; flex: 0 0 auto; }

/* 화살표는 한글 폰트에 없는 글리프라 Manrope 로 그린다 */
.vg-btn__arrow { font-family: var(--font-en); font-weight: 800; }

.vg-textlink {
  border: 0;
  background: none;
  padding: 0;
  font-family: var(--font-kr);
  font-size: var(--fs-xs);
  color: var(--c-body);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.vg-textlink:hover { color: var(--c-ink); }

/* --- 플레이 화면: 무대 --------------------------------------------------
   왼쪽에 인물 컷, 오른쪽에 대화. 원래는 대화창만 있었는데, 랜딩에서 얼굴을 보고
   들어온 사람이 판이 시작되는 순간 그 얼굴을 잃었다 — 회의실에 마주 앉았다는
   설정인데 화면에는 말풍선만 남는다.
   그래서 플레이 카드만 720px 규격에서 벗어나 980px 를 쓴다. 사진 한 단(200px)이
   들어갈 자리가 필요한데, 대화 폭을 그만큼 줄이면 말풍선이 세로로 길어진다. */

.vg-play { max-width: 980px; }

.vg-stage {
  display: grid;
  grid-template-columns: 200px minmax(0, 1fr);
  gap: 28px;
  align-items: start;
}

/* 대화가 길어져도 사진은 눈에 남아 있어야 한다 — 붙여 둔다.
   (로그가 자체 스크롤이라 페이지가 길어질 일은 별로 없지만, 좁은 창에서
    도구 버튼까지 내려가면 사진이 위로 빠져나간다) */
.vg-persona {
  position: sticky;
  top: 24px;
}

.vg-persona__shot {
  position: relative;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--c-panel);
  aspect-ratio: 4 / 5;
}

.vg-persona__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* 사진 아래쪽을 눌러 캡션이 얹히기 좋게 만든다 (랜딩 .vg-feature__veil 과 같은 수) */
.vg-persona__veil {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(10, 9, 9, 0) 45%, rgba(10, 9, 9, 0.55) 100%);
}

.vg-persona__cap {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 12px;
}

.vg-persona__name {
  font-size: var(--fs-body-lg);
  font-weight: 700;
  color: var(--c-ink);
  line-height: 1.2;
}

.vg-persona__role {
  font-size: var(--fs-2xs);
  line-height: var(--lh-body);
  color: var(--c-body);
}

.vg-chat { min-width: 0; }

/* --- 플레이 화면: 상단 바 ----------------------------------------------- */

/* ★ 붙여 둔다(sticky). 플레이 카드는 노트북 화면(720px)보다 높아서, 입력창을
   쓰려고 아래로 스크롤하면 이 바가 화면 위로 빠져나갔다 — 미션 한 줄과 남은 턴이
   판 내내 가장 자주 확인하는 두 정보인데 정작 말을 쓰는 동안 안 보였다.
   카드와 같은 면(--c-surface)을 깔아 대화 로그가 밑으로 지나가게 한다. */
/* ★ 0.12.0 — 이 띠는 아래 실선 하나로만 잘려 있었다. 다크 화면에서는 깔아 둔
   면(--c-surface)이 결국 상자로 읽히는데 좌우 안여백이 0 이라, 미션 문장이 그
   상자 모서리에 그대로 붙어 있었다. 화면의 다른 상자들과 같은 문법으로 맞춘다 —
   안여백 + 라운드(--r-md) + 1px 헤어라인. */
.vg-bar {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--c-surface);
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  margin-top: 10px;
  margin-bottom: 4px;
  padding: 14px 18px;
  border: 1px solid var(--c-line);
  border-radius: var(--r-md);
}

/* 미션 한 줄과 (보스전에서만) 명예 줄이 왼쪽에 세로로 선다. */
.vg-bar__left {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.vg-bar__mission {
  font-size: var(--fs-xs);
  line-height: var(--lh-body);
  color: var(--c-ink-soft);
  margin: 0;
}

/* --- 보스전 상단의 명예 줄 (0.12.0) ---------------------------------------
   판 내내 떠 있어야 하는 정보다 — 면접관의 온도가 여기서 갈리는데, 로그 맨 위의
   안내 상자는 몇 턴만 지나면 스크롤 밖으로 나간다. 뱃지 문법은 랜딩의 명예 특성
   줄(.vg-honors)과 같은 자를 쓴다: 같은 것이 두 화면에서 다르게 생기면 같은
   것으로 안 읽힌다. */
.vg-bar__honors {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  font-size: var(--fs-2xs);
  line-height: var(--lh-ui);
}

.vg-bar__honors[hidden] { display: none; }

.vg-bar__honors-label { color: var(--c-mute); font-weight: 600; }

.vg-bar__honors-none { color: var(--c-mute); }

.vg-bar__honors-badge {
  padding: 2px 8px;
  border: 1px solid var(--c-line);
  border-radius: var(--r-full);
  color: var(--c-ink-soft);
  font-weight: 600;
}

.vg-bar__honors-badge--quote { color: var(--c-accent); }

.vg-turns { flex: 0 0 auto; text-align: right; }

.vg-turns__num {
  font-family: var(--font-en);
  font-size: var(--fs-lg);
  font-weight: 700;
  /* 오렌지는 수치 강조에만 (§1-3). 라벨은 회색, 숫자만 오렌지 */
  color: var(--c-accent);
  line-height: 1;
}

.vg-turns__label {
  display: block;
  font-size: var(--fs-2xs);
  color: var(--c-body);
  margin-top: 4px;
}

.vg-track {
  display: flex;
  gap: 4px;
  justify-content: flex-end;
  margin-top: 8px;
  /* 연장 면접(0.13.0)이 붙으면 칸이 18개까지 늘어난다. 좁은 화면에서 한 줄로
     버티면 상단 바가 가로로 밀리므로 두 줄로 접히게 둔다(0.11.0 의 가로 흔들림
     수정과 같은 이유). */
  flex-wrap: wrap;
  row-gap: 4px;
}

.vg-track__pip {
  width: 6px;
  height: 6px;
  border-radius: var(--r-full);
  background: var(--c-ink);
}
.vg-track__pip[data-spent='true'] { background: var(--c-line); }

/* --- 대화 영역 (§4-15 스펙 그대로) -------------------------------------- */

.vg-log {
  height: clamp(320px, 46vh, 480px);
  overflow-y: auto;
  /* ★ 이 줄을 지우면 대화창 끝에서 페이지가 통째로 스크롤된다 (§4-15) */
  overscroll-behavior: contain;
  background: var(--c-page);
  border: 1px solid var(--c-line-soft);
  border-radius: var(--r-md);
  padding: 20px;
  margin-top: 20px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* 대화 로그 맨 위 지문 — 상황을 다시 읽게 해 준다. 말풍선이 아니라 무대 지시문 톤 */
.vg-brief {
  padding: 12px 14px;
  border-radius: var(--r-md);
  background: var(--c-panel);
  border: 1px dashed var(--c-line);
}

.vg-brief__text {
  font-size: var(--fs-2xs);
  line-height: var(--lh-body);
  color: var(--c-body);
  margin: 0;
  white-space: pre-line;
}

/* 무대 한 줄 (0.6.0) — 브리핑의 첫 줄이다. 화마다 다른 장소·시간을 여기서 세운다.
   상황 설명(setup)보다 한 단 밝게 둔다: 어디에 앉아 있는지가 먼저 읽혀야 지문의
   소품(국수 그릇·머그·개찰구)이 뜬금없이 보이지 않는다. */
.vg-brief__stage {
  font-size: var(--fs-2xs);
  line-height: var(--lh-body);
  font-weight: 600;
  color: var(--c-ink-soft);
  margin: 0 0 8px;
}

/* 📡 사내 소문통(grapevine) 특성일 때만 붙는 귀띔 한 줄. 서버가 briefExtra 로
   내려보낸다 — 없으면 이 줄 자체가 그려지지 않는다. */
.vg-brief__extra {
  font-size: var(--fs-2xs);
  line-height: var(--lh-body);
  color: var(--c-accent-soft);
  margin: 8px 0 0;
  padding-top: 8px;
  border-top: 1px dashed var(--c-line);
}

.vg-turn { display: flex; flex-direction: column; gap: 6px; }
.vg-turn--me { align-items: flex-end; }

.vg-gesture {
  font-size: var(--fs-2xs);
  color: var(--c-body);
  font-style: italic;
  margin: 0;
}

/* 내가 말 대신 행동을 한 턴. 오른쪽 정렬은 부모 .vg-turn--me 의 align-items 가
   이미 해 준다.
   ★ 0.17.0 — 점선 상자를 버리고 **오렌지 면**으로 바꿨다. 이 파일 머리말의
     "오렌지 면은 히어로 CTA 하나뿐" 규칙에 대한 의도된 예외가 둘째로 하나 생긴
     것이다. 이유: 행동은 한 턴을 통째로 쓰고 크레딧(또는 게이트의 행동 횟수)까지
     내고 지르는 수(手)인데, 점선 회색 상자는 로그에서 제일 조용한 요소였다 —
     제일 큰 값을 치른 것이 제일 안 보였다. 이제 로그에서 가장 센 한 줄이다.
   ★ 지문(.vg-gesture)에서 물려받는 기울임과 작은 글자를 여기서 되돌린다.
     상대의 몸짓보다 한 단 크고 굵다 — 같은 층위가 아니라 한 단 위다. */
.vg-gesture--act {
  max-width: 84%;
  padding: 11px 16px;
  border: 0;
  border-radius: var(--r-md);
  background: var(--c-accent);
  color: var(--c-invert-ink);
  font-size: var(--fs-body);
  font-weight: 700;
  font-style: normal;
  line-height: var(--lh-body);
  letter-spacing: var(--ls-tight);
  white-space: pre-wrap;
  /* 검정 로그 위에서만 보이는 번짐. 새 색이 아니라 --c-accent(#F47B1A)의 알파다
     (.vg-btn--accent 와 같은 문법 — accent 를 바꾸면 이 줄도 함께 고칠 것). */
  box-shadow: 0 8px 22px -14px rgba(244, 123, 26, 0.75);
}

.vg-bubble {
  max-width: 84%;
  padding: 12px 16px;
  border-radius: var(--r-md);
  font-size: var(--fs-sm);
  line-height: var(--lh-body);
  white-space: pre-wrap;
  margin: 0;
}

.vg-bubble--them { background: var(--c-panel-alt); color: var(--c-ink); }

/* 재생 중인 상대 대사 (0.17.0 · js/villain.js 의 typeInto). 대사는 이미 다 도착해
   있고 화면이 앞에서부터 흘려 줄 뿐인데, 그동안 끝에 커서 한 칸이 서 있어야
   "지금 말하는 중" 으로 읽힌다. 재생이 끝나면 클래스가 떨어지며 함께 사라진다.
   ★ 정보는 하나도 없다 — 재생을 끊으면 그 자리에서 전문이 들어간다. */
.vg-bubble--typing::after {
  content: '';
  display: inline-block;
  width: 2px;
  height: 1em;
  margin-left: 2px;
  vertical-align: -0.15em;
  background: var(--c-accent);
  animation: vg-caret 0.9s steps(1, end) infinite;
}

@keyframes vg-caret {
  0%, 49% { opacity: 1; }
  50%, 100% { opacity: 0; }
}
/* 내 말풍선만 밝은 면이다 — 다크 화면에서 "내가 말한 것"을 색으로 가른다 */
.vg-bubble--me { background: var(--c-invert); color: var(--c-invert-ink); }

/* --- 난입한 사람 (0.6.0 cameo) --------------------------------------------
   다른 화의 인물이 지나가다 한두 문장 얹는 자리다. 상대의 말풍선과 **한눈에**
   달라야 한다 — 같은 회색 말풍선이면 빌런이 두 마디 한 것으로 읽히고, 그러면
   난입이라는 사건이 화면에서 사라진다. 면은 한 단 어둡게(로그 바닥과 같은 검정),
   왼쪽에 선을 세우고, 이름표를 위에 붙인다. 오렌지 면은 쓰지 않는다(§1 규칙). */
.vg-cameo__who {
  font-size: var(--fs-2xs);
  font-weight: 700;
  color: var(--c-accent-soft);
  margin: 0;
}

.vg-bubble--cameo {
  background: var(--c-page);
  color: var(--c-ink-soft);
  border: 1px solid var(--c-line);
  border-left: 3px solid var(--c-accent);
}

/* 상태 한 줄 — 신념 접촉·방어도 변화를 알려 준다. 게이지 숫자는 노출하지 않는다.
   세 단계에 무게를 다르게 준다. 신념(--core)은 오렌지 + 볼드로 판의 사건이고,
   누그러짐(--down)은 잉크색 한 단계로 "가고 있다"만 알린다. 굳음은 기본 회색이다.
   누그러짐까지 오렌지로 칠하면 신념이 열리는 순간의 무게가 사라진다. */
.vg-note {
  font-size: var(--fs-2xs);
  margin: 0;
  color: var(--c-body);
}
.vg-note--core { color: var(--c-accent); font-weight: 600; }
.vg-note--down { color: var(--c-ink-soft); font-weight: 500; }

/* 속마음이 한 겹 열린 턴(표면 → 원칙의 가장자리 → 신념). 신념(--core)만큼의
   사건은 아니지만 누그러짐(--down)보다는 크다. 그래서 오렌지를 쓰지 않고
   잉크 + 굵기 + 왼쪽 선으로 한 단계 위에 둔다. */
.vg-note--open {
  color: var(--c-ink);
  font-weight: 600;
  border-left: 2px solid var(--c-accent);
  padding-left: 10px;
  line-height: var(--lh-body);
  text-wrap: pretty;
}

/* 판이 그대로 끝난 자리. 선을 넘는 행동 하나로 대화가 닫히고 결과도 나오지
   않으므로, 다른 상태 줄과 같은 회색으로 두면 무슨 일이 일어났는지 안 읽힌다.
   위에 선을 하나 그어 "여기서 끝" 을 보이게 한다. */
.vg-note--stop {
  color: var(--c-ink);
  font-weight: 600;
  border-top: 1px solid var(--c-line);
  padding-top: 14px;
  margin-top: 6px;
}

/* 돌발 이벤트가 터진 턴 (0.6.0). 겹이 열린 줄(--open)과 같은 층위의 사건이라
   같은 문법(왼쪽 선 + 잉크)을 쓰되 선을 점선으로 둔다 — 이건 내가 만든 진척이
   아니라 판이 흔들린 것이고, 겹처럼 되돌릴 수 없는 성과도 아니다.
   ★ 턴을 소모하지 않는다. 그래서 남은 턴 표시가 안 줄어드는데, 이 줄이 없으면
     "왜 갑자기 상대가 두 번 말했나"가 화면에서 설명되지 않는다. */
.vg-note--event {
  color: var(--c-ink);
  font-weight: 600;
  border-left: 2px dashed var(--c-accent);
  padding-left: 10px;
  line-height: var(--lh-body);
  text-wrap: pretty;
}

/* 닫힌 판에서 나갈 문. 판이 닫히면 화면의 버튼이 전부 잠기고 밑줄 글자 하나만
   남아서, 어디를 눌러야 다시 할 수 있는지가 안 읽혔다. 끝난 자리에 세운다. */
.vg-note__actions { margin-top: 4px; }

/* 귓속말 — 슬랙 DM 처럼 보이게 해서 세계관을 깨지 않는다 */
.vg-whisper {
  border: 1px solid var(--c-line);
  border-left: 3px solid var(--c-accent);
  border-radius: var(--r-md);
  background: var(--c-panel);
  padding: 14px 16px;
}

.vg-whisper__from {
  font-size: var(--fs-2xs);
  font-weight: 600;
  color: var(--c-body);
  margin: 0 0 6px;
}

.vg-whisper__text {
  font-size: var(--fs-sm);
  line-height: var(--lh-body);
  color: var(--c-ink);
  margin: 0;
  white-space: pre-wrap;
}

/* 귓속말이 치르는 값. 결과 화면의 '귓속말 −8' 이 어디서 온 감점인지 여기서 이어진다.
   경고색을 쓰지 않는다 — 잘못한 일이 아니라 스스로 고른 거래다. */
.vg-whisper__cost {
  font-size: var(--fs-2xs);
  color: var(--c-body);
  margin: 8px 0 0;
}

/* --- 크레딧이 모자랄 때 ----------------------------------------------------
   귓속말·행동을 누를 크레딧이 없을 때 대화 로그 안에 뜨는 상자다. 여기서 바로
   글을 열 수 있어야 한다 — 랜딩으로 나가서 벌어 오라고 하면 그 순간 판이 사라지고,
   판을 버리면서까지 크레딧을 벌 사람은 없다(글은 새 탭에서 열린다).
   귓속말 상자와 달리 왼쪽 띠를 두지 않는다: 누가 한 말이 아니라 화면의 안내다. */
.vg-gate {
  border: 1px dashed var(--c-line);
  border-radius: var(--r-md);
  background: var(--c-panel);
  padding: 14px 16px;
}

.vg-gate__head {
  margin: 0 0 6px;
  font-size: var(--fs-xs);
  font-weight: 700;
  color: var(--c-ink);
}

.vg-gate__sub {
  margin: 0;
  font-size: var(--fs-2xs);
  line-height: var(--lh-body);
  color: var(--c-body);
}

/* 상자 안의 글 한 줄은 목록에서 쓰던 것을 그대로 쓴다. 여백만 이 상자에 맞춘다. */
.vg-gate .vg-post {
  margin-top: 10px;
  padding: 12px 0 0;
  border-bottom: 0;
  border-top: 1px solid var(--c-line-soft);
}

/* 판정 대기 — '대화 마무리' 를 누른 뒤 10~30초짜리 판정 호출이 도는 구간.
   점 세 개만으로는 멈춘 건지 도는 건지 알 수 없어서, 초 카운터와 단계 문구를
   함께 얹은 상자를 쓴다. 귓속말(.vg-whisper)과 같은 폭·같은 라운드로 두되
   왼쪽 띠를 넣지 않아 "누가 말한 것"이 아니라 "시스템이 일하는 중"으로 읽힌다. */
/* ★ 0.6.0 에서 손댄 것은 **시각뿐**이다. 단계 문구 · 초 카운터 · 성공/실패 동작은
     한 글자도 바꾸지 않는다(README §2). 더한 것은 상자 맨 위를 지나가는 2px
     빛줄기 하나 — 진행률이 아니라 '아직 돈다'의 그림이다. 남은 시간을 아는 척하는
     막대는 두지 않았다: 10초에 끝날 수도 30초가 걸릴 수도 있어서 거짓말이 된다. */
.vg-judging {
  position: relative;
  overflow: hidden;
  border: 1px dashed var(--c-line);
  border-radius: var(--r-md);
  background: var(--c-panel);
  padding: 14px 16px;
}

.vg-judging::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 2px;
  background: linear-gradient(90deg,
              rgba(244, 123, 26, 0) 0%, var(--c-accent) 50%, rgba(244, 123, 26, 0) 100%);
  animation: vg-sweep 1.9s linear infinite;
}

@keyframes vg-sweep {
  from { transform: translateX(-100%); }
  to   { transform: translateX(100%); }
}

.vg-judging__head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 6px;
}

.vg-judging__title {
  font-size: var(--fs-2xs);
  font-weight: 600;
  color: var(--c-ink);
}

/* 초 카운터. 이 숫자가 올라가는 게 "안 멈췄다"의 유일한 증거라 tabular-nums 로
   자리를 고정한다 — 폭이 흔들리면 그것 자체가 불안하게 읽힌다. */
.vg-judging__clock {
  margin-left: auto;
  /* 계기판처럼 보이게 필 한 겹만 두른다. 숫자가 흔들리지 않게 자리를 고정하는
     tabular-nums 와 같은 목적이다 — 이 숫자는 장식이 아니라 증거다. */
  padding: 2px 8px;
  border-radius: var(--r-full);
  background: rgba(254, 254, 254, 0.06);
  font-family: var(--font-en);
  font-size: var(--fs-2xs);
  font-variant-numeric: tabular-nums;
  color: var(--c-ink-soft);
}

.vg-judging__step {
  font-size: var(--fs-sm);
  line-height: var(--lh-body);
  color: var(--c-ink);
  margin: 0;
}

.vg-judging__note {
  font-size: var(--fs-2xs);
  line-height: var(--lh-body);
  color: var(--c-body);
  margin: 6px 0 0;
}

/* 대기 표시 — 문화 챗봇과 같은 점 세 개 */
.vg-typing { display: inline-flex; gap: 5px; align-items: center; }
.vg-typing span {
  width: 5px;
  height: 5px;
  border-radius: var(--r-full);
  background: var(--c-body);
  animation: vg-bounce 1.1s infinite ease-in-out;
}
.vg-typing span:nth-child(2) { animation-delay: 0.15s; }
.vg-typing span:nth-child(3) { animation-delay: 0.3s; }

@keyframes vg-bounce {
  0%, 60%, 100% { transform: translateY(0); opacity: 0.45; }
  30% { transform: translateY(-4px); opacity: 1; }
}

/* --- 입력 --------------------------------------------------------------- */

/* 입력창이 여러 줄로 자라므로 보내기 버튼을 아래에 붙여 둔다 — 가운데 정렬이면
   세 줄짜리 입력에서 버튼이 공중에 뜬다. */
.vg-compose {
  display: flex;
  align-items: flex-end;
  gap: 10px;
  margin-top: 16px;
}

/* ★ <input> 이 아니라 <textarea> 다. 한 줄 입력창에서는 긴 문장을 쓰는 동안
   앞부분이 왼쪽으로 밀려 나가 자기가 쓴 말을 볼 수 없었다.
   높이는 js 의 autoGrow() 가 scrollHeight 로 잡고, 여기 max-height 에서 멈춘다
   (그 뒤로는 입력창 자체가 스크롤된다 — 대화 로그를 밀어내지 않는다).
   line-height 를 여기서 고정하는 게 중요하다: 이 값이 흔들리면 한 줄일 때의
   높이가 보내기 버튼(44px)과 어긋난다. */
.vg-input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 11px 18px;
  border: 1px solid var(--c-line);
  border-radius: 22px;
  background: var(--c-surface);
  font-family: var(--font-kr);
  font-size: var(--fs-sm);
  line-height: 20px;
  color: var(--c-ink);
  letter-spacing: var(--ls-tight);
  resize: none;
  /* 한계에 닿으면 js 의 autoGrow() 가 auto 로 켠다. 기본이 auto 면 높이가 딱
     맞는 순간에도 브라우저가 스크롤바를 그려 넣는다. */
  overflow-y: hidden;
  max-height: 160px;
  /* 44px = 20(줄) + 22(패딩) + 2(테두리). 보내기 버튼과 같은 높이에서 시작한다 */
  min-height: 44px;
}
.vg-input::placeholder { color: var(--c-mute); }
.vg-input:focus { outline: none; border-color: var(--c-ink); }
.vg-input:disabled { background: var(--c-panel); }

/* --- 행동 모드 -------------------------------------------------------------
   '행동하기' 를 누르면 이 입력창에 쓰는 것이 대사가 아니라 몸짓이 된다.
   그 전환이 화면에서 보여야 한다 — 안 보이면 방금 쓴 한 줄이 말로 나갈지
   지문으로 나갈지 모른 채 Enter 를 치게 된다. 그래서 테두리와 바닥을 함께 바꾼다.
   ★ 오렌지를 '면' 으로 쓰는 유일한 예외적 사용이다. 8% 는 색면이 아니라 물든
     바닥이고, 그것도 모드가 켜져 있는 동안만이다. 값은 --c-accent(#F47B1A) 를
     그대로 푼 것이다 — 토큰에 rgb 채널 변수가 없어서 여기만 숫자로 적는다.
     accent 색을 바꾸면 이 두 줄도 같이 고칠 것. */
.vg-compose[data-mode="act"] .vg-input,
.vg-compose[data-mode="act"] .vg-input:focus {
  border-color: var(--c-accent);
  background: rgba(244, 123, 26, 0.08);
}

/* 행동 모드 안내. 예시를 회색으로 늘어놓아 "무엇을 적을 수 있는지" 를 보여 준다.
   placeholder 는 한 줄이라 예시 하나밖에 못 담는다(모바일에서 잘린다). */
.vg-acthint {
  margin: 9px 4px 0;
  font-size: var(--fs-2xs);
  line-height: var(--lh-body);
  color: var(--c-mute);
}

.vg-send {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: var(--r-full);
  background: var(--c-invert);
  color: var(--c-invert-ink);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background 0.2s ease;
}
.vg-send:hover { background: var(--c-white); }
.vg-send:disabled { opacity: 0.4; cursor: default; }
.vg-send svg { width: 17px; height: 17px; }

.vg-tools {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  justify-content: space-between;
  margin-top: 14px;
}

.vg-tools__left { display: flex; gap: 8px; flex-wrap: wrap; }

/* --- 결과 화면 ---------------------------------------------------------- */

/* 결과 머리 — 점수가 맨 위다.
   이 자리에 원래 '엔딩 A' 라는 알파벳이 제일 크게 떠 있었다. 플레이어에게는
   뜻이 없는 글자다(A~E 기준은 서버 채점 규칙이라 화면에 나오지 않는다).
   지금은 100점 만점 점수가 가장 크고, 엔딩은 이름으로만 부른다. */
.vg-headline {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* 통과·탈락 배지 (0.13.0 · 보스전 전용).
   점수보다 먼저 읽혀야 하는 한 마디라 숫자 위에 세운다. 면을 칠하는 대신 테두리와
   글자색으로만 가른다 — 오렌지 면은 이 페이지에서 쓰지 않는다(§1 팔레트 규칙).
   ★ '탈락' 을 빨갛게 칠하지 않는다. 모의면접 결과가 채용과 무관하다는 고지와
     화면이 어긋나 보이고, 실패한 판을 화면이 나무라는 것처럼 읽힌다. */
.vg-headline__verdict {
  align-self: flex-start;
  font-family: var(--font-en);
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--c-body);
  border: 1px solid var(--c-line);
  border-radius: var(--r-full);
  padding: 5px 14px;
  margin: 0;
}
.vg-headline__verdict[data-pass='true'] {
  color: var(--c-accent);
  border-color: var(--c-accent);
}
.vg-headline__verdict[hidden] { display: none; }

/* 왜 통과인지·왜 탈락인지 한 줄. 확인되지 않은 항목 이름이 여기 그대로 뜬다. */
.vg-headline__why {
  font-size: var(--fs-2xs);
  line-height: var(--lh-body);
  color: var(--c-body);
  margin: 2px 0 0;
  text-wrap: pretty;
}
.vg-headline__why[hidden] { display: none; }

.vg-headline__score {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin: 0;
}

.vg-headline__num {
  font-family: var(--font-en);
  font-size: 64px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
  /* 오렌지는 수치 강조에만 쓴다(§1-3). 이 페이지에서 가장 중요한 수치다 */
  color: var(--c-accent);
  font-variant-numeric: tabular-nums;
}

.vg-headline__of {
  font-family: var(--font-en);
  font-size: var(--fs-body-lg);
  font-weight: 700;
  color: var(--c-body);
}

.vg-headline__title {
  font-size: var(--fs-lg);
  font-weight: 700;
  color: var(--c-ink);
  margin: 0;
}

.vg-headline__meta {
  font-size: var(--fs-2xs);
  color: var(--c-body);
  margin: 0;
}

/* 이 판을 어떤 조건으로 붙었나 (0.6.0). 점수 아래 한 줄. 점수 내역이 아니라
   맥락이라 --c-mute 로 한 단 낮춘다 — 특성은 채점에 들어가지 않는다. */
.vg-headline__trait {
  font-size: var(--fs-2xs);
  color: var(--c-mute);
  margin: 6px 0 0;
}
.vg-headline__trait[hidden] { display: none; }

/* 이 판으로 새로 열린 것 한 줄 (0.10.0 — 리롤권·명예 특성·명대사).
   판이 끝난 자리에서 유일하게 "다음"을 가리키는 문장이라 특성 줄보다 한 단 세운다.
   오렌지는 글자에만 — 면을 칠하지 않는다(§1 팔레트 규칙). */
.vg-headline__reward {
  font-size: var(--fs-2xs);
  font-weight: 600;
  color: var(--c-accent);
  margin: 6px 0 0;
  text-wrap: pretty;
}
.vg-headline__reward[hidden] { display: none; }

/* 후일담. 다크 개편 전에는 이 카드만 검게 뒤집어 호흡을 갈랐는데, 페이지가
   통째로 검어진 지금은 그 수가 통하지 않는다. 대신 카드보다 한 단 밝은 면 +
   왼쪽 오렌지 띠로 "여기서부터 다른 글" 이라고 표시한다. */
.vg-story {
  background: var(--c-panel-alt);
  border-left: 3px solid var(--c-accent);
  border-radius: var(--r-lg);
  padding: 28px;
  margin-top: 20px;
}

.vg-story__label {
  font-family: var(--font-en);
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--c-accent);
  margin: 0 0 14px;
}

.vg-story__text {
  font-size: var(--fs-sm);
  line-height: 1.85;
  color: var(--c-ink);
  margin: 0;
  white-space: pre-wrap;
}

/* 인재상 해금 — 채용 사이트 인재상 밴드의 푸른 기를 다크로 옮긴 --c-panel-blue */
.vg-unlock {
  background: var(--c-panel-blue);
  border: 1px solid var(--c-line-soft);
  border-radius: var(--r-lg);
  padding: 28px;
  margin-top: 20px;
}

.vg-unlock__no {
  font-family: var(--font-en);
  font-size: var(--fs-body-lg);
  font-weight: 700;
  color: var(--c-accent);
  margin: 0 0 4px;
}

.vg-unlock__label {
  font-size: var(--fs-team-name);
  font-weight: 700;
  color: var(--c-ink);
  margin: 0 0 10px;
}

.vg-unlock__canon {
  font-size: var(--fs-sm);
  font-weight: 500;
  line-height: var(--lh-body);
  color: var(--c-ink);
  margin: 0 0 16px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--c-line);
}

.vg-unlock__lesson {
  font-size: var(--fs-sm);
  line-height: var(--lh-body);
  color: var(--c-ink-soft);
  margin: 0;
}

.vg-unlock__hint {
  font-size: var(--fs-2xs);
  color: var(--c-body);
  margin: 14px 0 0;
}

/* 점수 바 — 총점은 화면 맨 위(.vg-headline)로 올라갔고, 여기는 내역만 남는다 */
.vg-scores__label {
  font-size: var(--fs-2xs);
  font-weight: 600;
  color: var(--c-body);
  margin: 24px 0 0;
}

.vg-scores { margin-top: 12px; display: grid; gap: 14px; }

.vg-score__head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  font-size: var(--fs-xs);
  margin-bottom: 6px;
}

.vg-score__name { color: var(--c-ink); font-weight: 600; }
.vg-score__name span { color: var(--c-body); font-weight: 500; margin-left: 6px; }
.vg-score__num { font-family: var(--font-en); font-weight: 700; color: var(--c-ink); }

.vg-score__bar {
  height: 6px;
  border-radius: var(--r-full);
  background: var(--c-line-soft);
  overflow: hidden;
}

.vg-score__fill {
  height: 100%;
  border-radius: var(--r-full);
  background: var(--c-ink);
}
.vg-score__fill--primary { background: var(--c-accent); }

/* --- 대화 전문 ----------------------------------------------------------
   이 게임의 결과물은 점수가 아니라 대화다. 남에게 보여줄 게 그거라서 결과
   화면에서 전문을 읽고 그대로 들고 나갈 수 있어야 한다.
   기본은 접어 둔다 — 결과를 보러 온 사람 앞에 열 턴짜리 로그를 먼저 펼치면
   후일담과 인재상이 화면 밖으로 밀린다. */

.vg-transcript__sum {
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--c-ink);
  list-style: none;
}
/* 사파리는 ::marker 를 안 지운다 — 웹킷 전용 의사요소로 한 번 더 지운다 */
.vg-transcript__sum::-webkit-details-marker { display: none; }

/* 접힘 표시를 직접 그린다. 브라우저 기본 삼각형은 다크 배경에서 잘 안 보이고,
   OS 마다 모양이 달라 다른 컴포넌트와 어긋난다. */
.vg-transcript__sum::before {
  content: '';
  width: 7px;
  height: 7px;
  border-right: 1.5px solid var(--c-body);
  border-bottom: 1.5px solid var(--c-body);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform 0.2s ease;
}
.vg-transcript[open] .vg-transcript__sum::before {
  transform: rotate(-135deg) translate(-2px, -2px);
}

.vg-transcript__count {
  margin-left: auto;
  font-family: var(--font-en);
  font-size: var(--fs-2xs);
  font-weight: 700;
  color: var(--c-body);
}

/* 대화 로그(.vg-log)와 같은 말풍선을 쓰되 높이를 고정하지 않는다 — 여기서는
   스크롤 없이 처음부터 끝까지 읽히는 게 목적이다. */
.vg-transcript__body {
  margin-top: 16px;
  padding: 20px;
  background: var(--c-page);
  border: 1px solid var(--c-line-soft);
  border-radius: var(--r-md);
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* 잘한 점 · 이렇게 했으면 더 좋았을 점.
   점수 바로 아래에 둔다 — 이 두 칸이 곧 그 점수의 설명이라, 명대사나 코멘트
   뒤로 밀면 숫자와 이유가 화면에서 떨어진다.
   두 칸을 나란히 놓고 '잘한 점' 에만 왼쪽 오렌지 띠를 준다. 아쉬운 쪽에 빨강을
   쓰지 않는다 — 이 페이지에 경고색이 없기도 하고, 다음에 해 볼 수를 적어 주는
   칸이지 틀렸다고 표시하는 칸이 아니다. */
/* ★ auto-fit 이 1fr 1fr 보다 낫다. 한 칸이 hidden 이면 빈 트랙이 접혀서 남은
   칸이 폭을 다 쓰고, 좁은 화면에서는 240px 아래로 눌리는 순간 저절로 한 단이
   된다 — 미디어 쿼리를 따로 두지 않아도 된다. */
.vg-review {
  margin-top: 22px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 14px;
}

.vg-review__card {
  background: var(--c-page);
  border: 1px solid var(--c-line-soft);
  border-left: 3px solid var(--c-line-strong);
  border-radius: var(--r-md);
  padding: 18px 20px;
}

.vg-review__card--good { border-left-color: var(--c-accent); }

.vg-review__label {
  font-size: var(--fs-2xs);
  font-weight: 700;
  color: var(--c-body);
  margin: 0 0 8px;
}

.vg-review__card--good .vg-review__label { color: var(--c-accent); }

.vg-review__text {
  font-size: var(--fs-xs);
  line-height: var(--lh-body);
  color: var(--c-ink);
  margin: 0;
}

/* 명대사 카드 — 캡처해서 올리는 게 이 게임의 확산 엔진이라 따로 만든다 */
.vg-quote {
  margin-top: 24px;
  border: 1px solid var(--c-line);
  border-radius: var(--r-md);
  padding: 20px;
  background: var(--c-page);
  display: grid;
  gap: 12px;
}

.vg-quote__row { display: flex; flex-direction: column; gap: 5px; }
.vg-quote__row--me { align-items: flex-end; }

.vg-quote__who { font-size: var(--fs-2xs); color: var(--c-body); }

.vg-quote__line {
  max-width: 88%;
  padding: 10px 14px;
  border-radius: var(--r-md);
  font-size: var(--fs-xs);
  line-height: var(--lh-body);
  margin: 0;
}
.vg-quote__row .vg-quote__line { background: var(--c-panel-alt); color: var(--c-ink); }
.vg-quote__row--me .vg-quote__line { background: var(--c-invert); color: var(--c-invert-ink); }

.vg-comment {
  font-size: var(--fs-sm);
  line-height: var(--lh-body);
  color: var(--c-ink-soft);
  margin: 20px 0 0;
  padding-left: 14px;
  border-left: 2px solid var(--c-line);
}

/* 결과 화면 하단 CTA — 인재상 섹션으로 보내는 게 이 페이지의 목적이다 */
.vg-cta {
  margin-top: 20px;
  background: var(--c-panel-alt);
  border-radius: var(--r-lg);
  padding: 28px;
  text-align: center;
}

.vg-cta__title {
  font-size: var(--fs-lg);
  font-weight: 700;
  color: var(--c-ink);
  margin: 0 0 8px;
}

.vg-cta__sub {
  font-size: var(--fs-sm);
  line-height: var(--lh-body);
  color: var(--c-ink-soft);
  margin: 0 0 20px;
}

.vg-cta .vg-actions { justify-content: center; margin-top: 0; }

.vg-foot {
  max-width: 720px;
  width: 100%;
  margin-top: 32px;
  font-size: var(--fs-2xs);
  line-height: var(--lh-body);
  color: var(--c-body);
  text-align: center;
}

/* altolab.ai 크레딧 링크 — 기존 푸터 글자색·크기 그대로, 터치 영역만 확보 */
.vg-foot__credit {
  display: inline-block;
  padding: 12px 8px;
  color: inherit;
  text-decoration: none;
}
.vg-foot__credit:hover { color: var(--c-ink-soft); }
/* updates.html 은 main 밖이라 본문 폭·여백을 직접 잡는다 */
.vg-foot--page { margin: 0 auto; padding: 0 var(--pad-x) 32px; }

.vg-error {
  font-size: var(--fs-xs);
  color: var(--c-ink-soft);
  margin: 12px 0 0;
}
.vg-error[hidden] { display: none; }

/* ==========================================================================
   버그·의견 제보 (0.14.0)
   --------------------------------------------------------------------------
   랜딩 맨 아래 한 줄 + 모달 안의 주관식 칸 하나. 새 색도 새 컴포넌트도 만들지
   않는다 — 버튼은 .vg-btn--ghost, 상자는 .vg-modal 을 그대로 쓰고 여기서는
   입력칸 하나와 그 주변 글자만 정한다.
   ★ 위에 실선을 하나 긋는다. 크레딧을 버는 곳(.vg-posts)과 제보는 성격이
     달라서, 경계가 없으면 '알고케어 이야기'의 마지막 줄로 읽힌다.
   ========================================================================== */

.vg-report {
  width: 100%;
  border-top: 1px solid var(--c-line-soft);
  padding-top: 28px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px 20px;
  text-align: center;
}

.vg-report__lead {
  margin: 0;
  font-size: var(--fs-2xs);
  line-height: var(--lh-ui);
  color: var(--c-mute);
}

/* 모달 안. 상자 폭(460px)에 맞춘 한 칸짜리 폼이다. */
.vg-report__form { margin-top: 18px; }

/* 대화 입력창(.vg-input)과 달리 자라지 않는다 — 여기서는 처음부터 넓은 판을
   주고 넘치면 스스로 스크롤한다. 판을 도는 중이 아니라 '적는 화면'이라
   높이가 왔다 갔다 하면 오히려 쓰다 만 글이 흔들린다. */
.vg-report__input {
  display: block;
  width: 100%;
  padding: 14px 16px;
  border: 1px solid var(--c-line);
  border-radius: var(--r-md);
  background: var(--c-panel);
  font-family: var(--font-kr);
  font-size: var(--fs-xs);
  line-height: var(--lh-body);
  color: var(--c-ink);
  letter-spacing: var(--ls-tight);
  resize: vertical;
  min-height: 160px;
  max-height: 46vh;
}
.vg-report__input::placeholder { color: var(--c-mute); }
.vg-report__input:focus { outline: none; border-color: var(--c-ink); }
.vg-report__input:disabled { opacity: 0.6; }

.vg-report__count {
  margin: 6px 0 0;
  font-size: var(--fs-2xs);
  color: var(--c-mute);
  text-align: right;
  font-variant-numeric: tabular-nums;
}
/* 상한에 닿았을 때만 색이 붙는다 — 늘 오렌지면 경고가 아니라 장식이다. */
.vg-report__count[data-full="true"] { color: var(--c-accent-soft); }

.vg-report__note {
  margin: 10px 0 0;
  font-size: var(--fs-2xs);
  line-height: var(--lh-ui);
  color: var(--c-mute);
  text-wrap: pretty;
}

/* 보내고 난 뒤. 폼 자리에 들어서는 한 덩어리라 위아래 숨만 준다. */
.vg-report__done {
  margin: 18px 0 0;
  font-size: var(--fs-xs);
  line-height: var(--lh-body);
  color: var(--c-ink-soft);
}

/* ==========================================================================
   체인지로그 (updates.html · 0.7.0)
   --------------------------------------------------------------------------
   랜딩·플레이·결과와 다른 화면(모달도 아니다)이라 .vg-landing/.vg-card 폭
   규칙을 그대로 물려받지 않고 자기 폭(720px, 결과 화면과 같다 — 읽는 화면
   이라는 성격이 같다)을 잡는다. 카드는 기존 .vg-card 를 그대로 쓴다.
   ========================================================================== */

.vg-updates {
  width: 100%;
  max-width: 720px;
  margin-top: 56px;   /* #vgPlay·#vgResult 와 같은 상단 숨(§1 골격 참고) */
}

.vg-updates__home {
  display: inline-block;
  margin-bottom: 20px;
}

.vg-updates__title {
  font-size: var(--fs-lg);
  font-weight: 700;
  letter-spacing: var(--ls-tight);
  color: var(--c-ink);
  margin: 0 0 8px;
}

.vg-updates__lead {
  font-size: var(--fs-sm);
  color: var(--c-body);
  margin: 0 0 28px;
}

.vg-updates__list {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.vg-updates__card-title {
  font-size: var(--fs-md);
  font-weight: 700;
  color: var(--c-ink);
  margin: 0 0 12px;
}

.vg-updates__items {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.vg-updates__items li {
  position: relative;
  padding-left: 16px;
  font-size: var(--fs-sm);
  line-height: var(--lh-body);
  color: var(--c-ink-soft);
}
/* 불릿을 리스트 마커가 아니라 점 하나로 직접 그린다 — base.css 리셋이
   ul { list-style: none } 라서 마커가 애초에 없다(§02). */
.vg-updates__items li::before {
  content: '';
  position: absolute;
  left: 2px;
  top: 0.65em;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--c-dim);
}

@media (max-width: 809.98px) {
  .vg-updates { margin-top: 32px; }
  .vg-updates__lead { margin-bottom: 20px; }
}

/* ==========================================================================
   모달 — 특성 뽑기 · 알고케어 퀴즈 (0.6.0)
   --------------------------------------------------------------------------
   이 페이지에는 시스템 확인창(confirm)이 한 군데도 없다(README §2). 그래서 자체
   오버레이를 쓴다. 카드와 같은 면·같은 라운드를 써서 "같은 화면의 한 단 위"로
   읽히게 한다 — 다른 사이트에서 온 팝업처럼 보이면 세계관이 끊긴다.
   ========================================================================== */

.vg-modal {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  /* 긴 문제·긴 설명이 작은 화면에서 잘리면 답을 고를 수 없다. 오버레이 자체가
     스크롤된다 — 안쪽 상자에 스크롤을 주면 그림자 없는 다크에서 잘린 게 안 보인다. */
  overflow-y: auto;
}
.vg-modal[hidden] { display: none; }

.vg-modal__scrim {
  position: absolute;
  inset: 0;
  background: rgba(10, 9, 9, 0.78);
}

/* --- 등장 · 퇴장 (0.6.0) -------------------------------------------------
   모달이 나타나고 사라지는 일 자체가 이 페이지에서 가장 큰 화면 전환이다.
   그냥 켜고 끄면 '팝업이 떴다'로 읽히고, 첫 방문자에게는 그게 광고 배너와
   같은 인상이 된다. 바닥은 배경을 덮으며 밝아지고 상자는 반 뼘 올라온다.
   ★ 퇴장은 js 가 .vg-modal--out 을 걸고 160ms 뒤에 hidden 을 준다 —
     hidden(display:none)은 트랜지션을 태울 수 없어서 클래스 한 겹이 필요하다.
     reverse 로 같은 키프레임을 되감아 쓴다(두 벌을 만들면 하나만 고치게 된다). */
@keyframes vg-scrim-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes vg-box-in {
  from { opacity: 0; transform: translateY(14px) scale(0.985); }
  to   { opacity: 1; transform: none; }
}

.vg-modal:not([hidden]) .vg-modal__scrim { animation: vg-scrim-in 0.2s ease both; }
.vg-modal:not([hidden]) .vg-modal__box   { animation: vg-box-in 0.3s var(--ease-out) both; }
.vg-modal--out .vg-modal__scrim { animation: vg-scrim-in 0.16s ease reverse both; }
.vg-modal--out .vg-modal__box   { animation: vg-box-in 0.16s ease reverse both; }

.vg-modal__box {
  position: relative;
  width: 100%;
  max-width: 460px;
  background: var(--c-surface);
  border: 1px solid var(--c-line);
  border-radius: var(--r-lg);
  padding: 28px;
  margin: auto;
}

/* 0.6.0 디자인 점검: 24px 제목 밑에 곧바로 13px 부제가 붙어 460px 상자 안에서
   위계가 두 칸 건너뛰었다(카드 제목은 22px, 그 밑 설명은 14px 이 이 사이트의 결이다
   — .vg-cta 참고). 한 칸씩 당겨 상자 크기에 맞춘다. */
.vg-modal__title {
  margin: 0;
  font-size: var(--fs-md);
  font-weight: 700;
  letter-spacing: var(--ls-tight);
  color: var(--c-ink);
}

.vg-modal__sub {
  margin: 10px 0 0;
  font-size: var(--fs-xs);
  line-height: var(--lh-body);
  color: var(--c-body);
  text-wrap: pretty;
}

.vg-modal__actions { margin-top: 20px; }

/* --- 뽑기 슬롯 ------------------------------------------------------------
   14장이 빠르게 돌다 감속해 멈춘다. 창은 한 칸(--slot-h)만 보이고, 릴 전체가
   위로 밀려 올라간다.
   ★ JS 는 --reel(몇 칸째인가, 소수 허용) 하나만 rAF 로 굴린다. transform 계산은
     CSS 가 한다 — 스타일 값을 자바스크립트가 문자열로 조립하기 시작하면 여기가
     곧 두 번째 스타일시트가 된다.
   ★ transition 을 걸지 않는다. 감속은 JS 의 이징이 만든다(둘을 겹치면 멈춤이
     두 번 미끄러진다). */
.vg-slot {
  --slot-h: 72px;
  --reel: 0;
  height: var(--slot-h);
  margin-top: 20px;
  overflow: hidden;
  border: 1px solid var(--c-line);
  border-radius: var(--r-md);
  background: var(--c-panel);
}

/* 멈춘 뒤. 도는 동안과 멈춘 뒤가 같은 상자면 '정해졌다'가 화면에 없다.
   테두리에 색이 들어오고 검정 위로 빛이 한 겹 번진다 — 면을 칠하지 않는다
   (오렌지 면은 히어로 CTA 하나뿐이다). 패널티는 같은 문법의 무채색 판이다:
   붉은색을 쓰지 않는 것과 같은 이유로, 벌이 아니라 오늘의 조건이다.
   js 는 land() 에서 data-landed 에 버프/패널티를 적기만 한다. */
.vg-slot[data-landed] {
  border-color: var(--c-line-strong);
  animation: vg-land 0.42s var(--ease-out) both;
}
.vg-slot[data-landed='buff'] {
  border-color: rgba(244, 123, 26, 0.55);
  box-shadow: 0 14px 36px -20px rgba(244, 123, 26, 0.75);
}

@keyframes vg-land {
  from { transform: scale(0.985); }
  60%  { transform: scale(1.008); }
  to   { transform: none; }
}

.vg-slot__reel {
  transform: translateY(calc(var(--reel) * var(--slot-h) * -1));
  will-change: transform;
}

.vg-slot__cell {
  height: var(--slot-h);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
  padding: 0 16px;
}

.vg-slot__name {
  font-size: var(--fs-body);
  font-weight: 700;
  color: var(--c-ink);
  letter-spacing: var(--ls-tight);
}
/* 버프는 오렌지 글자, 패널티는 한 단 낮춘 회색. 붉은색은 팔레트에 없다. */
.vg-slot__cell[data-type='buff'] .vg-slot__name { color: var(--c-accent); }
.vg-slot__cell[data-type='penalty'] .vg-slot__name { color: var(--c-mute); }

.vg-slot__type {
  font-size: var(--fs-2xs);
  font-weight: 600;
  color: var(--c-dim);
}

/* 멈춘 뒤 뜨는 효과 설명. role="status" 라 스크린리더가 결과를 여기서 읽는다
   (도는 동안 낱장이 읽히면 아무 뜻도 없어서 슬롯 자체는 aria-hidden 이다). */
.vg-slot__desc {
  margin: 12px 0 0;
  min-height: 1.7em;
  font-size: var(--fs-xs);
  line-height: var(--lh-body);
  color: var(--c-ink-soft);
  text-wrap: pretty;
}
/* 결과가 붙으면 한 단 올린다. 창 안의 이름이 제일 크고(18px), 이 줄이 그다음,
   버프/패널티 라벨이 제일 작다 — 셋이 같은 무게로 서 있으면 무엇이 정해졌는지
   눈이 못 고른다. (문장은 그대로다: 스크린리더가 결과를 이 줄로 읽는다) */
.vg-slot__desc:not(:empty) { color: var(--c-ink); }

/* --- 퀴즈 ----------------------------------------------------------------- */

.vg-quiz__q {
  margin: 20px 0 0;
  font-size: var(--fs-sm);
  font-weight: 600;
  line-height: var(--lh-body);
  color: var(--c-ink);
  text-wrap: pretty;
}

.vg-quiz__choices {
  margin-top: 16px;
  display: grid;
  gap: 8px;
}

/* 보기 네 개. 버튼이지만 pill 이 아니라 **줄**이다 — 네 개가 나란히 서야 읽고
   고르는 목록으로 보인다. 고른 뒤에는 전부 잠기고 고른 줄만 테두리로 남는다. */
.vg-quiz__choice {
  display: flex;
  gap: 10px;
  width: 100%;
  padding: 12px 14px;
  text-align: left;
  border: 1px solid var(--c-line);
  border-radius: var(--r-md);
  background: transparent;
  color: var(--c-ink);
  font-family: var(--font-kr);
  font-size: var(--fs-xs);
  line-height: var(--lh-body);
  cursor: pointer;
  transition: background 0.2s ease, border-color 0.2s ease;
}
.vg-quiz__choice:hover:not(:disabled) { background: var(--c-panel); }
.vg-quiz__choice:disabled { cursor: default; color: var(--c-body); }
.vg-quiz__choice[data-picked='true'] { border-color: var(--c-line-strong); color: var(--c-ink); }

.vg-quiz__no {
  flex: 0 0 auto;
  font-family: var(--font-en);
  font-weight: 700;
  color: var(--c-dim);
}

/* 채점 한 줄. 맞히면 해설이 함께 붙는다(오답에는 정답을 알려 주지 않는다 —
   다른 문제로 다시 붙게 하려는 것이다. 서버도 정답 번호를 내려보내지 않는다). */
.vg-quiz__verdict {
  margin: 16px 0 0;
  padding: 12px 14px;
  border-radius: var(--r-md);
  background: var(--c-panel);
  border: 1px dashed var(--c-line);
  font-size: var(--fs-2xs);
  line-height: var(--lh-body);
  color: var(--c-ink-soft);
  text-wrap: pretty;
}
.vg-quiz__verdict[hidden] { display: none; }
.vg-quiz__verdict[data-ok='true'] { color: var(--c-ink); border-color: var(--c-accent); }

.vg-quiz__links {
  margin: 18px 0 0;
  font-size: var(--fs-2xs);
  line-height: var(--lh-body);
  color: var(--c-mute);
}
.vg-quiz__links a { color: var(--c-accent-soft); text-decoration: underline; text-underline-offset: 3px; }


/* --- 태블릿 -------------------------------------------------------------
   히어로가 두 단으로 서기엔 좁아지는 구간. 사진 카드를 조금 줄여서
   헤드라인이 세 줄 넘게 접히지 않게 한다. */

@media (min-width: 810px) and (max-width: 1199.98px) {
  .vg-hero { gap: 40px; }
  .vg-hero__art { flex-basis: 340px; }

  /* 대화 폭이 먼저다. 사진 단을 줄여서 말풍선이 세로로 길어지는 걸 막는다 */
  .vg-stage { grid-template-columns: 160px minmax(0, 1fr); gap: 20px; }
}

/* --- 모바일 -------------------------------------------------------------
   히어로가 한 단으로 접힌다. 이때 사진이 헤드라인 아래로 내려가는데,
   순서를 바꾸지 않는다 — 광고로 들어온 사람이 먼저 읽어야 하는 건 한 문장이고,
   사진은 그 문장을 확인해 주는 그림이다. */

@media (max-width: 809.98px) {
  /* ── 리빌·호버는 통째로 끈다 ──────────────────────────────────────────
     getlayers 도 모바일에서는 같은 것을 끈다(카탈로그 §2-4 · 공통 원칙 3).
     손가락에는 호버가 없어서 --lift 가 켜지면 '탭했더니 안 꺼지는' 상태가 남고,
     진입 리빌은 스크롤이 이미 시작된 화면에서 글자만 늦게 따라오게 만든다.
     ★ js 가 인라인 style 로 값을 쓰기 때문에 !important 가 필요하다 —
       그게 없으면 인라인이 이긴다. 값을 0 으로 못 박으면 파생 효과 넷이
       한 줄로 전부 꺼진다(변수 하나로 굴린 값). */
  .vg-ep, .vg-btn { --lift: 0 !important; --btn-hover: 0 !important; }
  .vg-reveal { animation: none !important; opacity: 1 !important; transform: none !important; }

  .vg-page { padding: 0 20px 64px; }
  #vgResult { margin-top: 32px; }
  /* 플레이 카드만 위 숨을 줄인다 — 아래 계산에서 이 12px 이 도구 버튼을 화면
     안으로 들이는 데 쓰인다(§모바일 한 화면). 결과 화면은 읽는 화면이라 그대로. */
  #vgPlay { margin-top: 20px; }

  .vg-hero { gap: 32px; padding: 32px 0 56px; }
  .vg-hero__copy { gap: 20px; }
  .vg-hero__art { flex-basis: auto; width: 100%; }
  .vg-feature__cap { padding: 20px; }
  .vg-glow { top: -220px; height: 480px; }

  /* 오늘의 나 — 좁은 화면에서는 버튼을 아래로 내리고 폭을 다 준다. 옆에 세우면
     '퀴즈 풀고 다시 뽑기' 가 두 줄로 접히면서 상자가 세 줄이 된다. */
  .vg-today { margin-bottom: 32px; padding: 14px 16px; gap: 12px; }
  .vg-today__reroll { width: 100%; justify-content: center; }
  /* 손잡이 둘도 같은 이유로 세로로 쌓는다 — 좁은 화면에서 나란히 세우면 라벨이
     둘 다 두 줄로 접힌다(0.18.0). */
  .vg-today__acts { width: 100%; flex-direction: column; }

  .vg-eps { padding-bottom: 56px; }
  /* 무대도 한 단으로 접힌다. 사진이 먼저, 과제·시작 버튼이 그 아래다 —
     히어로에 있을 때와 같은 순서다(문장 → 그림 → 손잡이). */
  .vg-eps__stage { gap: 20px; margin-bottom: 28px; }
  .vg-eps__stage .vg-feature { flex-basis: auto; width: 100%; }
  .vg-eps__list { grid-template-columns: 1fr; }
  /* 장면 칩은 이모지만 남긴다 — 낱말까지 두면 인재상 이름 줄이 두 줄로 접힌다.
     무대가 어디인지는 브리핑 첫 줄이 문장으로 다시 말해 준다.
     낱말이 빠지면 필도 벗긴다: 이모지 한 글자를 테두리로 감싸면 그것만 단추처럼
     보인다. */
  .vg-ep__scene-word { display: none; }
  .vg-ep__scene { padding: 0; background: none; }
  /* 썸네일과 번호는 그대로 두고 난이도 글자만 뺀다 — 점 세 개로 충분하고,
     34px 짜리 글자가 붙으면 인재상 이름이 두 줄로 접힌다.
     화살표 칸도 지운다(호버가 없는 화면이라 영영 안 열리는 15px 이다). */
  .vg-ep { grid-template-columns: 22px 40px 1fr auto; gap: 10px; padding: 14px 4px; }
  .vg-ep::after { display: none; }
  .vg-ep__thumb { width: 40px; height: 50px; }
  .vg-ep__level { display: none; }

  /* 글 목록도 한 줄씩 세운다. 좁은 화면에서는 제목이 두 줄까지 접히므로 버튼을
     세로 가운데가 아니라 위쪽에 맞춰 두 줄짜리 제목 옆에 나란히 서게 한다. */
  .vg-posts { padding-bottom: 48px; }
  .vg-posts__list { grid-template-columns: 1fr; }
  .vg-post { gap: 12px; padding: 14px 4px; align-items: flex-start; }
  .vg-post__claim { min-width: 92px; margin-top: 2px; }
  /* 대화 로그 안(크레딧 안내 상자)은 폭이 더 좁다. 버튼을 옆에 세우면 제목이
     세 줄로 접히므로 여기서는 글 아래로 내린다. */
  .vg-gate .vg-post { flex-direction: column; align-items: stretch; }
  .vg-gate .vg-post__claim { width: 100%; margin-top: 10px; }

  .vg-card { padding: 20px; border-radius: var(--r-md); }
  .vg-story, .vg-unlock, .vg-cta { padding: 20px; }
  /* ── 모바일 한 화면 ────────────────────────────────────────────────────
     플레이 카드가 375×812 에서 829px 였다. 위 내비까지 더하면 906px —
     도구 버튼 세 개('행동하기 · 귓속말 · 대화 마무리')가 통째로 화면 밖에
     있었다는 뜻이다. 매 턴마다 그걸 쓰려고 스크롤을 해야 했고, 행동 모드를
     켜면 안내 한 줄이 붙어 버튼이 또 아래로 밀렸다.
     로그 높이(50svh → 44svh)와 위아래 숨을 깎아 한 화면에 들인다.
     ★ vh 가 아니라 svh 다 — 모바일 주소창이 펼쳐진 상태(가장 작은 높이)를
       기준으로 잡아야 실제로 안 잘린다.
     ★ 0.5.0 에서 상단 바에 크레딧 잔액 한 줄(23px)이 붙었다. 그만큼을 로그에서
       도로 뺀다(44svh → 41svh ≈ 24px). 이 화면은 늘리면 다른 데서 빼야 하는
       화면이다 — 한쪽만 늘리면 도구 버튼이 화면 밖으로 나간다.
     ⚠️ 0.6.0 에서 고친 것: 위 두 문단이 각각 따로 닫혀 있어서 둘째 문단이 주석
       밖으로 나와 있었다. 그 글자가 뒤따르는 `.vg-log` 선택자를 통째로 삼켜서
       (CSS 오류 복구는 여는 중괄호까지 먹는다) **모바일 로그 높이 41svh 가 아예
       적용되지 않았다** — 데스크톱 값(46vh)이 그대로 쓰여 도구 줄이 밀렸다.
       주석을 하나로 합쳐 살렸다. 주석 안에 주석 닫는 기호를 글자로 적지 말 것.
       0.6.0 에서 상단 바에 붙은 특성 표시는 크레딧과 같은 줄이라 높이 예산을 더
       먹지 않는다. */
  .vg-log { height: 41svh; padding: 16px; margin-top: 14px; }
  /* 좁은 화면에서는 두 칸을 위아래로 눕힌다(0.12.0). 나란히 두면 오른쪽의 턴
     트랙(보스전은 칸이 15개다)이 폭을 다 가져가 미션 한 줄이 다섯 줄로 접혔다 —
     명예 줄이 붙으면서 그 손해가 더 커졌다. 미션과 명예가 한 줄씩 쓰고, 턴·잔액이
     그 아래 오른쪽에 선다. */
  .vg-bar { padding: 12px 14px; flex-wrap: wrap; gap: 10px; }
  .vg-bar__left { flex: 1 1 100%; }
  .vg-turns { flex: 1 1 100%; }
  /* 잔액은 남은 턴 아래 한 줄로만. 라벨을 작게 두고 위 여백을 줄여 붙인다. */
  .vg-credit--bar { margin-top: 6px; }
  .vg-transcript__body { padding: 16px; }
  .vg-bubble { max-width: 90%; }
  .vg-actions .vg-btn { flex: 1 1 auto; justify-content: center; }

  /* 좁은 화면에서는 인물 컷을 옆에 세울 자리가 없다. 대화 위에 가로 띠로 눕힌다 —
     얼굴은 남기고 세로 공간은 최소로 쓴다(사진 56px). sticky 도 푼다: 모바일에서
     붙은 요소는 주소창이 접히고 펴질 때 같이 흔들려서 읽기가 나빠진다. */
  .vg-play { max-width: 100%; }
  .vg-stage { grid-template-columns: 1fr; gap: 16px; }
  .vg-persona {
    position: static;
    display: flex;
    align-items: center;
    gap: 12px;
  }
  .vg-persona__shot {
    flex: 0 0 auto;
    width: 56px;
    height: 56px;
    border-radius: var(--r-md);
    aspect-ratio: auto;
  }
  /* 세로 4:5 컷을 정사각으로 자르면 얼굴이 아래로 잘린다 — 위쪽을 잡아 준다 */
  .vg-persona__img { object-position: 50% 22%; }
  .vg-persona__veil { display: none; }
  .vg-persona__cap { margin-top: 0; gap: 2px; min-width: 0; }
  .vg-persona__name { font-size: var(--fs-sm); }

  /* ── 도구 버튼 두 줄 ───────────────────────────────────────────────────
     넓은 화면의 배치(왼쪽에 버튼 셋, 오른쪽에 '처음으로')를 좁은 화면에 그대로
     두면 폭이 295px 뿐이라 세 줄로 접혀 128px 을 먹었다. 여기서는 2열 격자로
     정해 놓는다 — 접히는 대로 두지 않고 자리를 지정해 두 줄(96px)에 앉힌다.
     ·  [행동하기] [귓속말]
     ·  [대화 마무리] ······ 처음으로
     display:contents 로 .vg-tools__left 를 지워 세 버튼이 격자 칸에 직접 앉는다
     (마크업을 건드리지 않고 순서를 정하려면 이 방법뿐이다). */
  .vg-tools {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px 10px;
    align-items: center;
    margin-top: 10px;
  }
  .vg-tools__left { display: contents; }
  /* 행동 모드에서만 붙는 안내 한 줄. 이 줄이 붙으면 도구 버튼이 그만큼 내려가므로
     좁은 화면에서는 위 숨을 줄여 둘째 줄이 화면 안에 남게 한다. */
  .vg-acthint { margin: 6px 2px 0; }
  /* 한 칸이 140px 남짓이다. 라벨이 두 줄로 접히면 아래 줄이 화면 밖으로 밀리므로
     안여백과 글자를 조여 한 줄을 지킨다(js 쪽 귓속말 라벨도 짧게 유지한다). */
  .vg-tools .vg-btn {
    width: 100%;
    justify-content: center;
    padding: 11px 8px;
    font-size: 13px;
  }
  #vgAct { grid-column: 1; }
  #vgHint { grid-column: 2; }
  #vgFinish { grid-column: 1; }
  #vgQuit { grid-column: 2; justify-self: end; }

  /* 보스전은 도구가 하나 더 많다(0.12.0 · 인상 · 인재상 · 행동 · 명대사 ·
     마치기 · 처음으로). 자리를 못 박아 두면 여섯 개가 네 자리에 겹치므로 지정을
     풀고 마크업 순서대로 흐르게 둔다 — 두 개씩 세 줄로 앉는다. */
  .vg-play--boss .vg-tools > *,
  .vg-play--boss .vg-tools__left > * { grid-column: auto; }
  .vg-play--boss #vgQuit { justify-self: end; }

  .vg-headline__num { font-size: 48px; }

  /* 모달 — 화면 폭을 다 쓰고 안여백만 줄인다. 슬롯 칸도 한 단 낮춘다(뽑기 모달이
     첫 방문의 첫 화면이라 320px 에서도 한 화면에 들어와야 한다). */
  .vg-modal { padding: 16px; }
  .vg-modal__box { padding: 20px; border-radius: var(--r-md); }
  .vg-slot { --slot-h: 64px; }
  .vg-modal__actions .vg-btn { flex: 1 1 auto; justify-content: center; }
}

/* --- 모션 끄기 ---------------------------------------------------------- */

/* 움직임을 줄여 달라고 한 사람에게는 **연출을 전부 세운다.** 상태 표시는 남긴다 —
   호버의 밝기·색(--lift 에서 나오는 바닥과 회색 빼기)은 정보이고, 움직이는 것
   (썸네일 확대·리빌·빛줄기·모달 등장)만 끈다. 뽑기 슬롯이 돌지 않는 것은
   js 쪽 motionOk() 가 이미 맡고 있다(결과만 세운다). */
@media (prefers-reduced-motion: reduce) {
  .vg-typing span { animation: none; }
  .vg-btn:hover { transform: none; }
  .vg-reveal { animation: none; }
  .vg-ep__thumb { transform: none; }
  .vg-judging::before { animation: none; opacity: 0.35; }
  .vg-slot[data-landed] { animation: none; }
  .vg-modal:not([hidden]) .vg-modal__scrim,
  .vg-modal:not([hidden]) .vg-modal__box,
  .vg-modal--out .vg-modal__scrim,
  .vg-modal--out .vg-modal__box { animation: none; }
}
.no-motion .vg-typing span { animation: none; }

/* ============================================================================
   보스전 — 모의면접 (0.8.0)
   ----------------------------------------------------------------------------
   "더 화려하고 근엄하게"가 기획인데, 알고케어 디자인 시스템(career-site
   DESIGN_GUIDE.md)의 규칙 안에서 만든다:
     · 오렌지는 면(面)이 아니다 — 점·글자·작은 마커·아이콘만 (§1-3)
     · 선은 1px 헤어라인 하나다 — 이중 선·장식 테두리를 만들지 않는다
     · 이유브로우는 Manrope 700 · letter-spacing 0.08em (.vg-eyebrow 와 동일)
   격식은 장식이 아니라 **면의 선택**에서 온다 — 보스전의 면은 --c-panel-blue 다.
   채용 사이트 인재상 밴드(.ways)와 이 사이트 인재상 해금 카드가 쓰는 바로 그
   푸른 기라서, "여기가 인재상을 검증하는 자리다"가 색으로 이어진다.
   ========================================================================== */

/* --- 목록의 보스 줄 ------------------------------------------------------ */

.vg-ep--boss {
  background: var(--c-panel-blue);
  border: 1px solid var(--c-line-strong);
}

.vg-ep__no--boss {
  color: var(--c-accent);
  letter-spacing: 0.08em;
}

/* 실사 컷이 있다 — 기본 썸네일과 같은 규칙(grayscale·scale·200%)을 그대로 받고,
   보스 줄임을 헤어라인 하나로만 구분한다. */
.vg-ep__thumb--boss {
  border: 1px solid var(--c-line);
}

.vg-ep__way--boss { color: var(--c-ink); }

.vg-ep__level--boss {
  width: auto;
  color: var(--c-accent-soft);
  font-weight: 700;
}

.vg-ep--boss.vg-ep--locked { background: var(--c-panel); }

/* --- 안내 모달 ----------------------------------------------------------- */

.vg-bossmodal { border: 1px solid var(--c-line-strong); }

.vg-bossmodal__who {
  font-size: var(--fs-2xs);
  font-weight: 700;
  color: var(--c-ink-soft);
  margin: 0 0 12px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--c-line);
}

/* 안내문은 규칙 목록이다(0.12.0) — 줄글로 늘어놓으면 다섯 줄이 한 덩어리로 읽혀
   아무도 안 읽는다. 점 하나를 앞에 세워 항목으로 만든다. 고지 성격의 줄
   (--notice)은 왼쪽에 오렌지 띠가 이미 서 있어서 점을 붙이지 않는다. */
.vg-bossmodal__line {
  font-size: var(--fs-2xs);
  line-height: var(--lh-body);
  color: var(--c-body);
  margin: 0 0 8px;
  padding-left: 12px;
  position: relative;
}

.vg-bossmodal__line::before {
  content: '·';
  position: absolute;
  left: 2px;
  color: var(--c-mute);
}

/* 저장 고지 — 다른 안내와 같은 회색이면 고지가 아니다. 한 단 세운다.
   (오렌지 왼쪽 선 2px — "작은 마커" 규칙 안이다. 겹 열림 줄과 같은 문법) */
.vg-bossmodal__line--notice {
  color: var(--c-ink);
  font-weight: 600;
  border-left: 2px solid var(--c-accent);
  padding-left: 10px;
}

.vg-bossmodal__line--notice::before { content: none; }

/* --- 플레이 화면의 면접장 옷 --------------------------------------------- */

/* 카드가 통째로 푸른 기를 입는다 — 회의실 열 판과 한눈에 다른 판이어야 한다.
   장식은 없다. 면과 헤어라인이 전부다. */
.vg-play--boss {
  background: var(--c-panel-blue);
  border-color: var(--c-line-strong);
}

.vg-play--boss .vg-bar { border-color: var(--c-line-strong); }

/* --- 로그 맨 위의 보스전 안내 상자 --------------------------------------- */

.vg-bossguide {
  padding: 18px 16px;
  border: 1px solid var(--c-line-strong);
  border-radius: var(--r-md);
  background: var(--c-panel);
  text-align: center;
}

/* .vg-eyebrow 와 같은 자(Manrope 700 · 0.08em) — 이 사이트의 이유브로우는
   하나의 자로 잰다. 자간을 더 벌리면 그 순간 다른 사이트의 글자가 된다. */
.vg-bossguide__eyebrow {
  font-family: var(--font-en);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--c-accent);
  margin: 0 0 6px;
}

.vg-bossguide__title {
  font-size: var(--fs-sm);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--c-ink);
  margin: 0 0 12px;
}

.vg-bossguide__stage {
  font-size: var(--fs-2xs);
  line-height: var(--lh-body);
  font-weight: 600;
  color: var(--c-ink-soft);
  margin: 0 0 12px;
  padding-bottom: 12px;
  border-bottom: 1px dashed var(--c-line);
}

/* 모달과 같은 문법 — 점 하나로 항목을 만든다(.vg-bossmodal__line 주석). */
.vg-bossguide__line {
  font-size: var(--fs-2xs);
  line-height: var(--lh-body);
  color: var(--c-body);
  margin: 0 0 6px;
  text-align: left;
  padding-left: 12px;
  position: relative;
}

.vg-bossguide__line::before {
  content: '·';
  position: absolute;
  left: 2px;
  color: var(--c-mute);
}

.vg-bossguide__line--notice {
  color: var(--c-ink);
  font-weight: 600;
  border-left: 2px solid var(--c-accent);
  padding-left: 10px;
}

.vg-bossguide__line--notice::before { content: none; }

/* --- 연출 지문 (beat) ----------------------------------------------------
   gesture 보다 큰 사건 — 면접관이 벌떡 일어난다든지. 가운데 정렬 + 오렌지
   마커 둘로 대화의 흐름을 한 번 끊는다. 마커는 "점·작은 마커" 규칙 안이다. */
.vg-beat {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin: 10px 0;
  text-align: center;
}

.vg-beat__orn {
  color: var(--c-accent);
  font-size: 10px;
  flex: none;
}

.vg-beat__text {
  font-size: var(--fs-2xs);
  line-height: var(--lh-body);
  font-style: italic;
  font-weight: 600;
  color: var(--c-ink-soft);
  text-wrap: pretty;
}

/* 전문 안에서는 지문 줄(.vg-gesture)의 문법을 따르되 눈에 띄게만 둔다. */
.vg-gesture--beat {
  color: var(--c-ink-soft);
  font-weight: 600;
}

/* 인상이 장전된 것을 알리는 줄 — 진척 신호가 아니라 준비 상태라 점선. */
.vg-note--imp {
  color: var(--c-ink-soft);
  font-weight: 600;
  border-left: 2px dashed var(--c-line-strong);
  padding-left: 10px;
}

/* --- 아이콘 (0.12.0) -----------------------------------------------------
   인상 일곱 장·인재상·행동 뽑기가 쓰는 선 아이콘. 폰트 이모지를 걷어낸 이유는
   index.html 의 심볼 주석에 적어 뒀다. 색은 여기서 정하지 않는다 —
   currentColor 라 버튼·목록의 글자색을 그대로 받는다. */
.vg-ic {
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
  display: block;
}

/* 도구 버튼 안 — 글자보다 살짝 작게 두어야 라벨이 주인공으로 남는다. */
.vg-ic--btn { width: 16px; height: 16px; }

/* 고르기 목록 안 — 첫 줄의 글자와 눈높이를 맞춘다(목록은 baseline 정렬이다). */
.vg-ic--pick {
  width: 17px;
  height: 17px;
  align-self: center;
  color: var(--c-ink-soft);
}

.vg-btn__label { min-width: 0; }

/* --- 인상 고르기 상자 ----------------------------------------------------
   크레딧 게이트(.vg-gate)와 같은 층위 — 대화 로그 안에 뜨는 도구 상자다. */
.vg-imp {
  padding: 14px;
  border: 1px solid var(--c-line-strong);
  border-radius: var(--r-md);
  background: var(--c-panel);
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.vg-imp__head {
  font-size: var(--fs-2xs);
  font-weight: 700;
  color: var(--c-ink);
  margin: 0 0 4px;
}

.vg-imp__pick {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 9px 12px;
  border: 1px solid var(--c-line);
  border-radius: var(--r-sm);
  background: var(--c-panel-alt);
  color: var(--c-ink-soft);
  font-size: var(--fs-2xs);
  text-align: left;
  cursor: pointer;
}

.vg-imp__pick:hover { border-color: var(--c-line-strong); color: var(--c-ink); }

.vg-imp__name { font-weight: 700; flex: none; }

.vg-imp__desc { color: var(--c-mute); min-width: 0; }

.vg-imp__cancel { align-self: flex-end; }

@media (max-width: 809.98px) {
  /* 좁은 화면에서는 이름과 설명이 두 줄로 눕는다. 아이콘은 그 두 줄 왼쪽에
     그대로 서 있어야 하므로 격자로 바꾼다(세로로 눕히면 아이콘만 위에 뜬다). */
  .vg-imp__pick {
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: center;
    gap: 2px 10px;
  }
  .vg-imp__pick .vg-ic--pick { grid-row: span 2; }
  .vg-imp__desc { grid-column: 2; }
}

/* --- 인재상 리마인드 상자 (0.12.0) ---------------------------------------
   보스전의 컨닝 페이퍼. 값도 감점도 없는 스킬이라 상자도 조용해야 한다 —
   인상 상자와 같은 면·같은 라운드를 쓰되 고를 것이 없으니 버튼이 없다. */
.vg-values {
  padding: 14px;
  border: 1px solid var(--c-line-strong);
  border-radius: var(--r-md);
  background: var(--c-panel);
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.vg-values__head {
  margin: 0;
  font-size: var(--fs-2xs);
  font-weight: 700;
  color: var(--c-ink);
}

/* ★ flex 로 두지 않는다 — flex 컨테이너의 li 는 마커(1. 2. 3.)를 잃는다.
   열 개짜리 컨닝 페이퍼에서 번호는 장식이 아니라 '몇 개인지'를 세는 눈금이다. */
.vg-values__list {
  margin: 0;
  padding: 0 0 0 22px;
  list-style: decimal;
}

.vg-values__item {
  font-size: var(--fs-2xs);
  line-height: var(--lh-body);
  color: var(--c-mute);
  margin-bottom: 6px;
}

.vg-values__item::marker { color: var(--c-mute); }

.vg-values__label {
  color: var(--c-ink-soft);
  font-weight: 700;
  margin-right: 6px;
}

.vg-values__foot {
  margin: 2px 0 0;
  font-size: var(--fs-2xs);
  line-height: var(--lh-body);
  color: var(--c-mute);
  border-top: 1px dashed var(--c-line);
  padding-top: 8px;
}

.vg-values__cancel { align-self: flex-end; }

/* --- 행동 뽑기 상자 (0.12.0) ---------------------------------------------
   두 장을 눕혀 놓고 하나를 고르는 자리. 인상 상자와 같은 문법을 쓰되 점선
   테두리로 "값을 이미 치렀고 결과를 받는 중"이라는 것을 구분한다. */
.vg-act {
  padding: 14px;
  border: 1px dashed var(--c-line-strong);
  border-radius: var(--r-md);
  background: var(--c-panel);
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.vg-act__head {
  margin: 0;
  font-size: var(--fs-2xs);
  font-weight: 700;
  color: var(--c-ink);
}

.vg-act__sub {
  margin: -2px 0 2px;
  font-size: var(--fs-2xs);
  line-height: var(--lh-body);
  color: var(--c-mute);
}

.vg-act__pick {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 12px;
  border: 1px solid var(--c-line);
  border-radius: var(--r-sm);
  background: var(--c-panel-alt);
  color: var(--c-ink-soft);
  font-size: var(--fs-2xs);
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}

.vg-act__pick:hover { border-color: var(--c-line-strong); color: var(--c-ink); }

.vg-act__cancel { align-self: flex-end; }

/* --- 결과 화면의 면접 리포트 옷 ------------------------------------------ */

.vg-result--boss .vg-card { border-color: var(--c-line-strong); }

/* 리포트 카드에만 파란 면을 준다. 0.13.0 에서 그 위에 지원 CTA 가 한 장 더
   서면서 :first-child 로는 엉뚱한 상자가 파래졌다 — 그래서 id 로 못 박는다. */
.vg-result--boss #vgReportCard { background: var(--c-panel-blue); }

/* 보스전 결과 최상단의 지원 CTA (0.13.0).
   결과 카드보다 위에 서는 유일한 상자다. 아래쪽 인재상 CTA 와 같은 모양이면
   같은 것이 두 번 나온 것으로 읽히므로, 여기만 테두리를 둘러 한 단 세운다.
   ★ margin-top 을 지운다 — 화면 맨 위라 위에 밀어낼 것이 없다.
   ★ 이 자리에 둔 이유는 순서다. 위의 .vg-result--boss .vg-card 가 테두리 색을
     덮어쓰므로 그보다 뒤에 와야 오렌지 테두리가 살아남는다. */
.vg-result--boss .vg-cta--apply {
  margin-top: 0;
  border-color: var(--c-accent);
}
.vg-cta--apply[hidden] { display: none; }

/* --- 명대사 (0.10.0) -----------------------------------------------------
   10화를 깨면 얻는 자격. 보스전 한 판에 한 번, 내 발화 하나가 결정적 한 마디로
   나간다. 화면에서 그 한 줄이 다른 답변과 달라 보여야 "한 번뿐인 것을 썼다"가
   읽힌다 — 다만 **면은 건드리지 않는다.** 내 말풍선의 밝은 면은 다크 화면에서
   "내가 말한 것" 한 종류뿐이고, 오렌지 면은 히어로의 시작 버튼 하나뿐이다(§1).
   그래서 남는 수단은 1px 헤어라인과 글자 굵기다. */
.vg-bubble--quote {
  border: 1px solid var(--c-accent);
  font-weight: 600;
}

/* 장전됐다는 줄. 인상(--imp)이 점선인 것과 달리 실선 오렌지다 — 이건 준비가 아니라
   한 번뿐인 것을 꺼내 든 순간이라 겹 열림 줄(--open)과 같은 무게에 둔다. */
.vg-note--quote {
  color: var(--c-accent);
  font-weight: 600;
  border-left: 2px solid var(--c-accent);
  padding-left: 10px;
  line-height: var(--lh-body);
}

/* ============================================================================
   빌런 게이트 던전 (0.16.0)
   ----------------------------------------------------------------------------
   보스전이 면(--c-panel-blue)으로 격식을 만든다면, 이쪽은 **선**으로 긴장을
   만든다. 새 색을 만들지 않는다(DESIGN_GUIDE §1 · 이 파일 머리말):
     · 오렌지(--c-accent)는 면이 아니다 — 치명타 라벨·버닝 테두리·통과 링처럼
       한순간 지나가는 빛과 작은 글자에만 쓴다.
     · 카드의 면은 --c-panel 하나다. 게이트 셋을 색으로 가르지 않는다 —
       난이도는 별(★)이 말한다.
   ★ 이 절의 움직이는 것은 전부 맨 아래 prefers-reduced-motion 블록에서 꺼진다.
     js 의 motionOk() 가 한 겹 더 막지만(연출을 아예 안 태운다), CSS 쪽도 함께
     닫아 둔다 — 한쪽만 있으면 다른 경로로 들어온 애니메이션이 살아남는다.
   ========================================================================== */

/* --- 랜딩 섹션 ----------------------------------------------------------- */

.vg-gates {
  width: 100%;
  max-width: var(--w-page);
  /* 위아래 같은 숨. 아래를 비워 두면 다음 섹션('알고케어 이야기') 제목이 카드
     밑동에 붙는다 — 랜딩의 섹션 간격은 각 블록이 자기 여백으로 만든다. */
  margin: 40px auto;
}

.vg-gates[hidden] { display: none; }

/* 규칙 두 줄. js 가 \n 하나로 이어 붙인 문자열을 넣으므로 pre-line 이어야 두 줄로
   선다(마크업에 <br> 을 박지 않는 이유 — 문구의 정본은 js 한 곳이다). */
.vg-gates__lead {
  margin: 0 0 16px;
  font-size: var(--fs-xs);
  line-height: var(--lh-body);
  color: var(--c-body);
  white-space: pre-line;
  text-wrap: pretty;
}

/* 오늘 남은 입장. 크레딧 칩과 같은 문법이다 — 숫자만 오렌지로 세운다. */
.vg-gates__chip {
  font-size: var(--fs-2xs);
  font-weight: 700;
  color: var(--c-accent-soft);
  white-space: nowrap;
}

.vg-gates__chip[hidden] { display: none; }

.vg-gates__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
}

.vg-gates__note {
  margin: 14px 0 0;
  font-size: var(--fs-2xs);
  line-height: var(--lh-body);
  color: var(--c-mute);
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: baseline;
}

.vg-gates__note[hidden] { display: none; }

/* 카드 한 장. 에피소드 줄(.vg-ep)과 달리 가로로 세 장이 서므로, 얼굴이 위에
   눕고 글이 아래로 온다 — 좁은 화면에서는 한 장씩 세로로 접힌다(아래 반응형).
   호버 값(--lift)은 js 가 굴리고 여기서 그 값으로 바닥·테두리를 정한다
   (이 파일의 인터랙션 규칙 — 스타일을 js 가 조립하지 않는다). */
.vg-gate {
  --lift: 0;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 14px;
  text-align: left;
  /* 바닥은 --lift 로 밝아진다(에피소드 줄과 같은 문법 — 흰빛을 아주 조금 얹는다). */
  background: var(--c-panel);
  box-shadow: inset 0 0 0 999px rgba(254, 254, 254, calc(var(--lift, 0) * 0.04));
  border: 1px solid var(--c-line);
  border-radius: var(--r-card);
  cursor: pointer;
}

.vg-gate__thumb {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  border-radius: var(--r-sm);
  border: 1px solid var(--c-line);
  background-color: var(--c-panel-alt);
  background-position: center 22%;
  background-size: cover;
  /* 얼굴 열 장과 같은 규칙 — 회색으로 눕히고 손끝이 오면 색이 돌아온다. */
  filter: grayscale(calc(1 - var(--lift)));
  transition: filter var(--dur-hover) var(--ease-out);
}

.vg-gate__main {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}

.vg-gate__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
}

.vg-gate__title {
  font-size: var(--fs-sm);
  font-weight: 700;
  letter-spacing: var(--ls-tight);
  color: var(--c-ink);
}

/* 난이도는 별로만 말한다. 12~13px 오렌지라 --c-accent-soft 를 쓴다(§1 규칙). */
.vg-gate__diff {
  font-size: var(--fs-2xs);
  color: var(--c-accent-soft);
  letter-spacing: 0.06em;
}

.vg-gate__done {
  font-size: var(--fs-2xs);
  font-weight: 600;
  color: var(--c-ink-soft);
}

.vg-gate__sub,
.vg-gate__meta {
  font-size: var(--fs-2xs);
  line-height: var(--lh-ui);
  color: var(--c-mute);
}

.vg-gate__sub { color: var(--c-body); }

/* 잠긴 카드 — 흐리게 두고 호버 값을 못 박는다(잠긴 에피소드 줄과 같은 규칙:
   누를 수 없는 것이 손끝을 따라 밝아지면 눌릴 것처럼 보인다). */
.vg-gate--locked {
  --lift: 0 !important;
  opacity: 0.5;
  cursor: default;
}

/* --- 설정 모달 ----------------------------------------------------------- */

/* 대상이 한 말. 판에 들어가기 전에 이 문장 하나만 읽고 들어간다 — 왼쪽에 오렌지
   띠를 세워 인용임을 표시한다(고지 줄과 같은 문법). */
.vg-gatemodal__remark {
  margin: 16px 0 0;
  padding: 10px 12px;
  border-left: 2px solid var(--c-accent);
  background: var(--c-panel);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  font-size: var(--fs-xs);
  line-height: var(--lh-body);
  color: var(--c-ink);
}

.vg-gateform { margin-top: 18px; }

.vg-gateform__label {
  margin: 16px 0 6px;
  font-size: var(--fs-2xs);
  font-weight: 700;
  color: var(--c-ink-soft);
  display: block;
}

.vg-gateform__label:first-child { margin-top: 0; }

.vg-gateform__input {
  width: 100%;
  padding: 10px 12px;
  background: var(--c-panel);
  border: 1px solid var(--c-line);
  border-radius: var(--r-sm);
  color: var(--c-ink);
  font-family: var(--font-kr);
  font-size: var(--fs-sm);
}

.vg-gateform__input:focus-visible {
  outline: none;
  border-color: var(--c-accent);
}

.vg-gateform__hint {
  margin: 6px 0 0;
  font-size: var(--fs-2xs);
  line-height: var(--lh-ui);
  color: var(--c-mute);
}

.vg-gateform__row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* 2택·3택 버튼. 고른 것은 면이 아니라 테두리와 글자로 표시한다(오렌지 면 금지). */
.vg-pick {
  padding: 8px 14px;
  background: var(--c-panel);
  border: 1px solid var(--c-line);
  border-radius: var(--r-full);
  color: var(--c-body);
  font-family: var(--font-kr);
  font-size: var(--fs-2xs);
  font-weight: 600;
  cursor: pointer;
}

.vg-pick:hover { border-color: var(--c-line-strong); color: var(--c-ink); }

.vg-pick[aria-pressed="true"] {
  border-color: var(--c-accent);
  color: var(--c-accent-soft);
}

/* --- 판 화면의 게이트 옷 ------------------------------------------------- */

/* 보스전이 면을 바꾸는 자리에서 이쪽은 테두리만 한 단 세운다 — 회의실 열 판과
   같은 면 위에서 벌어지는 일이고, 다른 것은 온도지 무대가 아니다. */
.vg-play--gate { border-color: var(--c-line-strong); }

/* 대상의 상태 한 줄. 숫자를 쓰지 않는다 — 인정 단계가 오를수록 글자만 밝아진다
   (게이지를 그리면 그 순간 대화가 눈금 맞추기가 된다). */
.vg-persona__admit {
  display: block;
  margin-top: 6px;
  font-size: var(--fs-2xs);
  font-weight: 600;
  color: var(--c-mute);
}

.vg-persona__admit[hidden] { display: none; }
.vg-persona__admit[data-admit="1"] { color: var(--c-body); }
.vg-persona__admit[data-admit="2"] { color: var(--c-ink-soft); }
.vg-persona__admit[data-admit="3"] { color: var(--c-accent-soft); }

/* 치명타 라벨 — 로그와 입력창 사이에 한 번 떠올랐다 사라진다. 자리를 차지하지
   않도록 절대 위치로 띄우고, 클릭도 먹지 않는다. */
/* 치명타 라벨의 기준 상자. .vg-chat 은 원래 position 이 없어서, 여기서
   relative 를 걸어 라벨이 대화 칸 안에 뜨게 한다(페이지 전체가 아니라). */
.vg-play--gate .vg-chat { position: relative; }

.vg-crit {
  position: absolute;
  right: 12px;
  bottom: 96px;
  margin: 0;
  font-family: var(--font-en);
  font-size: var(--fs-md);
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--c-accent);
  pointer-events: none;
  opacity: 0;
  z-index: 3;
}

.vg-crit[hidden] { display: none; }

@keyframes vg-crit-pop {
  0%   { opacity: 0; transform: translateY(10px) scale(0.9); }
  30%  { opacity: 1; transform: translateY(0) scale(1.06); }
  70%  { opacity: 1; transform: translateY(-4px) scale(1); }
  100% { opacity: 0; transform: translateY(-14px) scale(1); }
}

.vg-crit--on { animation: vg-crit-pop 0.9s var(--ease-out) both; }

/* 말풍선 타격 — 유효타는 짧게 흔들리고 은은히 번진다. */
@keyframes vg-hit {
  0%   { transform: translateX(0); }
  25%  { transform: translateX(-3px); }
  55%  { transform: translateX(2px); }
  100% { transform: translateX(0); }
}

.vg-turn--hit { animation: vg-hit 0.28s var(--ease-out) both; }

.vg-turn--hit .vg-bubble--them {
  box-shadow: 0 0 0 1px rgba(244, 123, 26, 0.3);
}

/* 치명타 — 흔들림이 크고 테두리에 오렌지가 한 겹 선다. */
@keyframes vg-crit-shake {
  0%   { transform: translate(0, 0); }
  15%  { transform: translate(-6px, 1px); }
  35%  { transform: translate(5px, -2px); }
  55%  { transform: translate(-4px, 2px); }
  75%  { transform: translate(3px, -1px); }
  100% { transform: translate(0, 0); }
}

.vg-turn--crit { animation: vg-crit-shake 0.42s var(--ease-out) both; }

.vg-turn--crit .vg-bubble--them {
  border-color: var(--c-accent);
  box-shadow: 0 0 18px rgba(244, 123, 26, 0.22);
}

/* 로그 컨테이너가 함께 흔들린다 — 한 대 맞은 것은 말풍선이 아니라 그 자리다. */
.vg-log--shake { animation: vg-crit-shake 0.42s var(--ease-out) both; }

/* 화면 가장자리 플래시. 면을 칠하는 것이 아니라 안쪽 테두리에 빛이 한 번
   번지는 것이다(오렌지 면 금지 규칙 안에 있다). */
@keyframes vg-edge-flash {
  from { box-shadow: inset 0 0 60px rgba(244, 123, 26, 0.26); }
  to   { box-shadow: inset 0 0 0 rgba(244, 123, 26, 0); }
}

.vg-play--flash { animation: vg-edge-flash 0.55s var(--ease-out) both; }

/* --- 버닝 모드 ----------------------------------------------------------- */

/* 치명타가 연달아 터지면 입력창 테두리가 달아오른다. 1단계는 테두리 색만,
   2단계는 글로우가 숨을 쉰다. miss 한 번에 식는다(js 가 data-burn 을 지운다). */
@keyframes vg-burn-pulse {
  0%, 100% { box-shadow: 0 0 10px rgba(244, 123, 26, 0.18); }
  50%      { box-shadow: 0 0 24px rgba(244, 123, 26, 0.42); }
}

.vg-compose[data-burn] .vg-input {
  border-color: var(--c-accent);
  box-shadow: 0 0 10px rgba(244, 123, 26, 0.18);
}

.vg-compose[data-burn="2"] .vg-input {
  animation: vg-burn-pulse 1.1s var(--ease-inout) infinite;
}

/* --- 통과 연출 ----------------------------------------------------------- */

.vg-clear {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  background: radial-gradient(circle at 50% 50%,
    rgba(244, 123, 26, 0.12) 0%, rgba(10, 9, 9, 0.72) 70%);
}

.vg-clear[hidden] { display: none; }

@keyframes vg-clear-ring {
  from { opacity: 0.9; transform: scale(0.2); }
  to   { opacity: 0;   transform: scale(2.4); }
}

.vg-clear__ring {
  position: absolute;
  width: 42vmin;
  height: 42vmin;
  border: 2px solid var(--c-accent);
  border-radius: 50%;
  opacity: 0;
}

.vg-clear--on .vg-clear__ring { animation: vg-clear-ring 1.1s var(--ease-out) both; }

.vg-clear--on .vg-clear__ring--slow {
  animation-duration: 1.6s;
  animation-delay: 0.16s;
  border-color: var(--c-accent-soft);
}

@keyframes vg-clear-text {
  0%   { opacity: 0; transform: scale(0.86); letter-spacing: 0.3em; }
  35%  { opacity: 1; transform: scale(1); letter-spacing: 0.12em; }
  80%  { opacity: 1; }
  100% { opacity: 0; }
}

.vg-clear__text {
  position: relative;
  margin: 0;
  font-family: var(--font-en);
  font-size: clamp(28px, 8vmin, 64px);
  font-weight: 700;
  letter-spacing: 0.12em;
  color: var(--c-ink);
  text-shadow: 0 0 24px rgba(244, 123, 26, 0.45);
  opacity: 0;
}

.vg-clear--on .vg-clear__text { animation: vg-clear-text 1.7s var(--ease-out) both; }

/* 파티클 — span 열여섯 개가 각자 자기 각도(--a)와 거리(--d)로 흩어진다.
   라이브러리를 쓰지 않는다(이 저장소에는 의존성이 없다 · README §2). */
.vg-clear__spark {
  position: absolute;
  width: 0;
  height: 0;
}

@keyframes vg-spark {
  from { opacity: 1; transform: rotate(var(--a)) translateY(0) scale(1); }
  to   { opacity: 0; transform: rotate(var(--a)) translateY(calc(var(--d) * -1)) scale(0.3); }
}

.vg-clear__dot {
  position: absolute;
  width: 6px;
  height: 6px;
  margin: -3px;
  border-radius: 50%;
  background: var(--c-accent);
  opacity: 0;
  transform-origin: center;
}

.vg-clear--on .vg-clear__dot {
  animation: vg-spark 1.1s var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 18ms);
}

/* --- 결과 화면의 게이트 옷 ----------------------------------------------- */

.vg-result--gate #vgReportCard { border-color: var(--c-line-strong); }

/* 게이트 결과의 두 손잡이 — '다시 도전하기' 와 '목록으로'. 여기서만 오렌지 면을
   쓴다(0.17.0).
   ★ 왜 게이트에서만인가: 빌런 판·보스전 결과 화면의 오렌지 면은 맨 아래 '알고케어
     인재상 보러 가기' 하나다(이 사이트의 유일한 전환 지점). 그 위에 오렌지를 두 개
     더 깔면 전환 버튼이 셋 중 하나가 된다. 게이트 결과에는 그 전환 카드가 붙지
     않고, 여기서 사람이 할 일은 '한 번 더' 아니면 '목록' 둘뿐이라 그 둘을 세운다.
   ★ 오늘 도전을 다 쓴 판에서는 이 버튼이 '내일 다시 열려요' 로 바뀐다. 그건
     주행동이 아니라 안내라서(눌러도 목록으로 돌아갈 뿐이다) 면을 다시 눕힌다 —
     표시는 js 가 거는 data-spent 다. */
.vg-result--gate #vgAgain,
.vg-result--gate #vgToList {
  background: var(--c-accent);
  color: var(--c-invert-ink);
  border-color: transparent;
  font-weight: 700;
}

.vg-result--gate #vgAgain:hover,
.vg-result--gate #vgToList:hover { background: var(--c-accent-hover); }

.vg-result--gate #vgAgain[data-spent='true'] {
  background: transparent;
  color: var(--c-ink);
  border-color: var(--c-line);
  font-weight: 600;
}
.vg-result--gate #vgAgain[data-spent='true']:hover { background: var(--c-panel); }

/* ★ hidden 이 display 를 못 이기는 자리 셋. 점수 줄(flex) · 점수 내역(grid) ·
   리뷰 두 칸(grid)은 display 가 박혀 있어서 js 가 hidden 을 걸어도 그대로 보인다 —
   점수가 없는 게이트 결과에서 '0 / 100점' 과 빈 리뷰 상자가 남았다.
   ★ 게이트만의 문제가 아니다: 빌런 판에서도 리뷰 두 칸이 다 비면(인신공격으로 끝난
     판) 같은 이유로 빈 상자가 남아 있었다. 그래서 게이트 선택자로 좁히지 않는다. */
#vgResult .vg-headline__score[hidden],
#vgResult .vg-scores[hidden],
#vgResult .vg-review[hidden] { display: none; }

/* 통과·실패 배지는 보스전과 같은 요소(#vgPassBadge)를 쓴다 — 그쪽 스타일이 이미
   data-pass 로 갈리므로 여기서 색을 다시 정하지 않는다. */

/* --- 좁은 화면 ----------------------------------------------------------- */

@media (max-width: 809px) {
  /* 카드 세 장이 가로로 서면 얼굴이 엄지만큼 작아진다 — 한 장씩 세로로 접고
     얼굴은 왼쪽 띠로 눕힌다(에피소드 줄과 같은 모양이 된다). */
  .vg-gates__list { grid-template-columns: 1fr; }
  .vg-gate { flex-direction: row; align-items: center; gap: 12px; }
  .vg-gate__thumb { width: 84px; flex: 0 0 84px; aspect-ratio: 3 / 4; }
  /* 손가락 화면에는 호버가 없다 — 값을 못 박아 두 겹으로 막는다(에피소드 줄과 같다). */
  .vg-gate { --lift: 0 !important; }
  .vg-gate__thumb { filter: grayscale(1); }
  .vg-crit { bottom: 84px; font-size: var(--fs-sm); }
}

/* --- 모션 끄기 ----------------------------------------------------------- */

/* 움직임을 줄여 달라고 한 사람에게는 이 절의 연출을 **전부** 세운다. js 의
   motionOk() 가 이미 연출을 태우지 않지만(그쪽이 1차 방어다), CSS 로도 닫아 둔다.
   ★ 정보는 하나도 안 사라진다 — 치명타·인정·통과는 모두 로그와 결과 화면의
     글자가 말한다. 여기서 끄는 것은 흔들림·번쩍임·파티클뿐이다. */
@media (prefers-reduced-motion: reduce) {
  .vg-crit--on,
  .vg-turn--hit,
  .vg-turn--crit,
  .vg-log--shake,
  .vg-play--flash,
  .vg-compose[data-burn="2"] .vg-input,
  .vg-clear--on .vg-clear__ring,
  .vg-clear--on .vg-clear__text,
  .vg-clear--on .vg-clear__dot { animation: none; }
  /* 대사 재생은 js 의 motionOk() 가 이미 안 태운다(그쪽이 1차 방어다). 커서만
     혹시 붙어도 깜박이지 않게 여기서 한 겹 더 닫는다. */
  .vg-bubble--typing::after { animation: none; opacity: 0; }
  .vg-gate__thumb { transition: none; }
}

/* ============================================================================
   내 설득 스타일 · 업적 (0.18.0)
   ----------------------------------------------------------------------------
   결과 화면과 같은 뼈대를 쓴다 — 큰 제목(.vg-headline__title) · 눈금(.vg-score__*) ·
   버튼 줄(.vg-actions). 판이 아니라 읽는 화면이므로 새 색도 새 모서리도 만들지
   않는다(이 파일 머리말 §1).
     · 면은 카드(--c-surface)와 그 안의 한 단(--c-panel) 둘뿐이다.
     · 오렌지는 이유브로우와 칭호 글자에만 — 면으로 쓰지 않는다.
     · 못 딴 업적은 붉은색이 아니라 흐린 글자다. 잠금 표시도 그림이 아니라 '미획득'
       이라는 글자다(이 페이지에 이모지를 쓰지 않는다).
   ========================================================================== */

#vgStyle { margin-top: 56px; }

/* 유형 설명 한두 문장. 결과 화면의 후일담(.vg-story__text)과 같은 무게다. */
.vg-style__desc {
  margin: 12px 0 0;
  font-size: var(--fs-sm);
  line-height: var(--lh-body);
  color: var(--c-ink-soft);
  text-wrap: pretty;
}

/* 기록 요약 — 이름과 값 두 칸. 표를 만들지 않는다(세 줄짜리 표는 표가 아니다). */
.vg-style__facts {
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
  display: grid;
  gap: 0;
}

.vg-style__fact {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding: 12px 0;
  border-bottom: 1px solid var(--c-line-soft);
}
.vg-style__fact:last-child { border-bottom: 0; }

.vg-style__fact-label {
  font-size: var(--fs-2xs);
  font-weight: 600;
  color: var(--c-mute);
}

.vg-style__fact-value {
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--c-ink);
}

/* 칭호 2택·N택. 버튼은 게이트 설정 모달과 같은 .vg-pick 이다 — 같은 사이트에서
   '고르는 줄' 이 두 종류로 생기면 안 된다. */
.vg-style__picks {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 12px;
}
.vg-style__picks[hidden] { display: none; }

.vg-style__note {
  margin: 10px 0 0;
  font-size: var(--fs-2xs);
  line-height: var(--lh-body);
  color: var(--c-mute);
}

/* --- 업적 그리드 --------------------------------------------------------- */

.vg-achv__count {
  margin: 0 0 12px;
  font-size: var(--fs-2xs);
  font-weight: 600;
  color: var(--c-body);
}

.vg-achv__grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

.vg-achv__item {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px 16px;
  border: 1px solid var(--c-line);
  border-radius: var(--r-md);
  background: var(--c-panel);
}

/* 못 딴 것은 같은 자리에 흐리게 눕는다 — 감추면 무엇을 모으는 중인지 알 수 없고,
   같은 밝기로 세우면 딴 것과 구별이 안 된다. */
.vg-achv__item[data-got='false'] {
  background: transparent;
  border-color: var(--c-line-soft);
}

.vg-achv__name {
  margin: 0;
  font-size: var(--fs-xs);
  font-weight: 700;
  color: var(--c-ink);
}
.vg-achv__item[data-got='false'] .vg-achv__name { color: var(--c-mute); }

.vg-achv__text {
  margin: 0;
  font-size: var(--fs-2xs);
  line-height: var(--lh-body);
  color: var(--c-body);
  text-wrap: pretty;
}
.vg-achv__item[data-got='false'] .vg-achv__text { color: var(--c-dim); }

.vg-achv__foot {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin: 2px 0 0;
  font-size: var(--fs-2xs);
}

.vg-achv__date {
  font-family: var(--font-en);
  font-weight: 700;
  color: var(--c-mute);
}

/* 칭호는 13px 짜리 오렌지 글자라 --c-accent-soft 자리다(base.css §01 규칙). */
.vg-achv__title {
  font-weight: 700;
  color: var(--c-accent-soft);
}

.vg-achv__lock {
  font-weight: 600;
  color: var(--c-dim);
}

/* --- 좁은 화면 ----------------------------------------------------------- */

@media (max-width: 809.98px) {
  #vgStyle { margin-top: 32px; }
  /* 두 칸으로 세우면 업적 이름이 한 글자씩 접힌다 — 한 줄에 한 장이다. */
  .vg-achv__grid { grid-template-columns: 1fr; }
  .vg-style__fact { padding: 10px 0; }
}

/* ============================================================================
   우리 회사 빌런 소환 · 친구 · 도전장 (0.18.0)
   ----------------------------------------------------------------------------
   게이트 섹션(.vg-gates)과 같은 문법이다 — 새 색도 새 모서리도 만들지 않는다.
     · 섹션 여백·머리 줄·안내 줄은 게이트의 것을 그대로 쓴다(.vg-gates__*).
     · 빌런 카드(.vg-scard)는 게이트 카드와 달리 얼굴이 없다 — 사연으로 만든
       인물이라 고를 컷이 없다. 그 자리를 이름·역할·겉모습 세 줄이 대신한다.
     · 오렌지는 이름 한 줄과 칭호 글자에만. 면으로 쓰지 않는다(파일 머리말 §1).
   ========================================================================== */

.vg-summon {
  width: 100%;
  max-width: var(--w-page);
  margin: 40px auto;
}

.vg-summon[hidden] { display: none; }

.vg-summon__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  /* 게이트는 늘 세 장이라 3열로 못 박았지만 이쪽은 0~여러 장이다 — 장 수에 따라
     칸이 늘어야 한 장만 있을 때 카드가 화면 폭을 다 먹지 않는다. */
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 12px;
}

.vg-summon__block { margin-top: 24px; }

.vg-summon__label {
  margin: 0 0 10px;
  font-size: var(--fs-2xs);
  font-weight: 700;
  color: var(--c-ink-soft);
}

.vg-summon__acts {
  margin-top: 16px;
  justify-content: flex-start;
}

/* --- 빌런 카드 ------------------------------------------------------------ */

.vg-scard {
  height: 100%;
  padding: 16px;
  background: var(--c-surface);
  border: 1px solid var(--c-line);
  border-radius: var(--r-md);
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.vg-scard__head { display: grid; gap: 2px; }

.vg-scard__name {
  margin: 0;
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--c-ink);
}

.vg-scard__role {
  margin: 0;
  font-size: var(--fs-2xs);
  color: var(--c-mute);
}

.vg-scard__surface {
  margin: 0;
  font-size: var(--fs-2xs);
  line-height: var(--lh-body);
  color: var(--c-body);
}

/* 그 사람이 실제로 한 말. 결과 화면의 인용 칸과 같은 무게로 세운다. */
.vg-scard__remark {
  margin: 0;
  padding-left: 10px;
  border-left: 2px solid var(--c-line-strong);
  font-size: var(--fs-2xs);
  line-height: var(--lh-body);
  color: var(--c-ink-soft);
}

.vg-scard__from,
.vg-scard__sent,
.vg-scard__note {
  margin: 0;
  font-size: var(--fs-2xs);
  line-height: var(--lh-ui);
  color: var(--c-mute);
}

.vg-scard__acts {
  margin-top: auto;
  padding-top: 8px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* 친구 고르는 줄. 카드 안에서 펼쳐지므로 카드 폭을 넘지 않아야 한다. */
.vg-scard__pick {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding-top: 8px;
  border-top: 1px solid var(--c-line-soft);
}

/* --- 친구 모달 ------------------------------------------------------------ */

.vg-friends__row {
  display: flex;
  gap: 8px;
  align-items: center;
}

/* 코드는 읽어서 옮겨 적는 글자라 자간을 벌리고 숫자 폭을 고정한다 — 0 과 O 를
   섞지 않으려고 서버가 혼동 글자를 뺐지만(api/friends.js), 붙어 있으면 그래도
   잘못 읽는다. */
.vg-friends__code {
  flex: 1 1 auto;
  padding: 10px 12px;
  background: var(--c-panel);
  border: 1px solid var(--c-line);
  border-radius: var(--r-sm);
  font-family: var(--font-en);
  font-size: var(--fs-sm);
  font-weight: 700;
  letter-spacing: 0.12em;
  color: var(--c-ink);
  font-variant-numeric: tabular-nums;
}

.vg-friends__form { margin-top: 16px; }
.vg-friends__form .vg-friends__row .vg-gateform__input { flex: 1 1 auto; }

.vg-friends__block { margin-top: 18px; }

.vg-friends__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.vg-friend {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  justify-content: space-between;
  padding: 10px 0;
  border-bottom: 1px solid var(--c-line-soft);
}

.vg-friend:last-child { border-bottom: 0; }

.vg-friend__main {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: baseline;
}

.vg-friend__name {
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--c-ink);
}

/* 칭호는 오렌지 글자 한 줄이다(업적 격자의 .vg-achv__title 과 같은 자리). */
.vg-friend__title {
  font-size: var(--fs-2xs);
  font-weight: 700;
  color: var(--c-accent-soft);
}

.vg-friend__note {
  font-size: var(--fs-2xs);
  color: var(--c-mute);
}

.vg-friend__acts {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

/* --- 소환 모달 ------------------------------------------------------------ */

/* 모달 머리의 소환진 띠. 히어로 그림과 같은 파일을 아래쪽만 잘라 쓴다 — 소환이
   무엇인지 말로 설명하기 전에 한 번 보여 주는 자리다. 글자가 위에 얹히지 않으므로
   면을 깔지 않고, 대신 위아래를 어둡게 눌러 모달 배경과 이어 붙인다. */
.vg-summonband {
  position: relative;
  height: 132px;
  margin: 0 0 18px;
  border-radius: var(--r-lg);
  overflow: hidden;
  border: 1px solid var(--c-line-soft);
}

.vg-summonband__img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* 그림의 아래쪽(바닥의 소환진)이 띠 한가운데 오게 내린다 */
  object-position: 50% 84%;
}

.vg-summonband::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom,
              rgba(10, 9, 9, 0.55), rgba(10, 9, 9, 0.12) 45%, rgba(10, 9, 9, 0.82));
  pointer-events: none;
}

.vg-summonform { margin-top: 18px; }

/* 고지는 입력창 **위**다. 적고 나서 읽는 고지는 고지가 아니라 변명이라, 이
   자리에서만 한 단 밝게 세운다(오렌지 면이 아니라 헤어라인 한 겹). */
.vg-summonform__notice {
  margin: 16px 0 0;
  padding: 10px 12px;
  background: var(--c-panel);
  border: 1px solid var(--c-line);
  border-radius: var(--r-sm);
  font-size: var(--fs-2xs);
  line-height: var(--lh-body);
  color: var(--c-ink-soft);
}

.vg-summonform__text {
  width: 100%;
  min-height: 110px;
  padding: 10px 12px;
  background: var(--c-panel);
  border: 1px solid var(--c-line);
  border-radius: var(--r-sm);
  color: var(--c-ink);
  font-family: var(--font-kr);
  font-size: var(--fs-sm);
  line-height: var(--lh-body);
  resize: vertical;
}

.vg-summonform__text:focus-visible {
  outline: none;
  border-color: var(--c-accent);
}

/* 만들어진 카드. 목록의 카드(.vg-scard)와 같은 뼈대인데 모달 안이라 면을 한 단
   낮춘다 — 모달 상자 위에 또 카드 면을 얹으면 층이 셋이 된다. */
.vg-summonprev {
  margin-top: 18px;
  padding: 14px;
  background: var(--c-panel);
  border: 1px solid var(--c-line);
  border-radius: var(--r-md);
  display: grid;
  gap: 6px;
}

.vg-summonprev__name {
  margin: 0;
  font-size: var(--fs-md);
  font-weight: 700;
  color: var(--c-ink);
}

.vg-summonprev__role {
  margin: 0;
  font-size: var(--fs-2xs);
  color: var(--c-mute);
}

.vg-summonprev__surface {
  margin: 0;
  font-size: var(--fs-xs);
  line-height: var(--lh-body);
  color: var(--c-body);
}

.vg-summonprev__remark {
  margin: 0;
  padding-left: 10px;
  border-left: 2px solid var(--c-line-strong);
  font-size: var(--fs-xs);
  line-height: var(--lh-body);
  color: var(--c-ink-soft);
}

/* --- 좁은 화면 ----------------------------------------------------------- */

@media (max-width: 809.98px) {
  .vg-summon { margin: 32px auto; }
  /* 한 줄에 한 장. 240px 두 장은 이 폭에서 이름이 접힌다. */
  .vg-summon__list { grid-template-columns: 1fr; }
}
