/* GROO — 블랙 · 건메탈 · 실버. 문로그의 글꼴 셋을 이어 받고 색은 더 어둡고 차갑게. 네온 없음. */
:root {
  --void: #050506;
  --void-2: #0b0c0e;
  --gun: #2a2d31;
  --steel: #8d9399;
  --silver: #c9ced4;
  --ink: #e6e8eb;
  --ink-2: #a3a9b0;
  --muted: #6c7279;
  --hair: rgba(230, 232, 235, 0.12);
  --hair-2: rgba(230, 232, 235, 0.22);
  --glint: #e3e9f0;
  --btn-line: rgba(230, 232, 235, 0.4); /* 누르는 것의 테두리 — 바탕 위 3:1 넘게 */
  --focus: #f3eee7;
  --f-display: "Instrument Serif", "Times New Roman", serif;
  --f-ui: "IBM Plex Sans KR", "Apple SD Gothic Neo", "Malgun Gothic", system-ui, sans-serif;
  --f-voice: "Gowun Batang", "Nanum Myeongjo", serif;
  --f-mono: "IBM Plex Mono", ui-monospace, Consolas, monospace;
  --gutter: clamp(16px, 4vw, 48px);
  color-scheme: dark;
}

* { box-sizing: border-box; }
html { background: var(--void); }
body {
  margin: 0;
  background: var(--void);
  color: var(--ink);
  font-family: var(--f-ui);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
button { font: inherit; color: inherit; }
a { color: inherit; }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; } /* 크림 2px — 3D 위에서도 보이게 */

#gl {
  /* 쪽 뒤 배경 — 화면에 붙어 있다(붙는 것은 이것 하나). 고정 구간이 끝나면 main.js 가 더 그리지 않아 끝 구도 그림으로 멈춘다 */
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  z-index: 0;
}

.skip-link {
  position: absolute;
  left: var(--gutter);
  top: -60px;
  z-index: 10;
  padding: 10px 14px;
  background: var(--void-2);
  border: 1px solid var(--btn-line);
  font-size: 13px;
  text-decoration: none;
}
.skip-link:focus { top: 12px; }

main { position: relative; z-index: 1; }

/* ── 장면 01·02 — 금고 ─────────────────────────────── */
#vault {
  position: relative;
  z-index: 2; /* 머리 · 카드 · 눈금자는 배경(#gl) · 어둠 판 위에서 문서와 같이 흐른다 */
  height: 100vh;
  height: 100svh;
  overflow: hidden;
}

/* 2D 빛 층 — 문틀 구멍 자리(--fx-x/y/r, 3D 에서 매 프레임 받음)에 붙는다 */
.fx {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: var(--fx, 0);
}
.fx-rays {
  position: absolute;
  left: var(--fx-x, 50%);
  top: var(--fx-y, 50%);
  width: calc(var(--fx-r, 200px) * 4.6);
  aspect-ratio: 1;
  transform: translate(-50%, -50%) rotate(var(--fx-rot, 0deg));
  -webkit-mask: radial-gradient(closest-side, transparent 0 41%, #000 44%, rgba(0, 0, 0, 0.55) 62%, transparent 100%);
  mask: radial-gradient(closest-side, transparent 0 41%, #000 44%, rgba(0, 0, 0, 0.55) 62%, transparent 100%);
  filter: blur(1.5px);
}
.fx-dust { position: absolute; inset: 0; width: 100%; height: 100%; }

/* 이름 — 왼쪽 위 글자로만(금고 위에는 아무 글도 없다). 워드마크 ⑤ GROO STUDIO 모노 한 줄, 위아래 가는 줄
   (④ 두 줄 쌓기는 높이 56px 이상 자리에서만 — og 그림) */
.title {
  position: absolute;
  left: var(--gutter);
  top: calc(32px + env(safe-area-inset-top)); /* 머리 위 여백 32(규격) — 안쪽 방 머리(.niche-head)와 같은 자리 */
  max-width: calc(100% - 2 * var(--gutter));
  text-shadow: 0 1px 14px rgba(0, 0, 0, 0.9);
  pointer-events: none;
}
.wm {
  display: inline-flex;
  gap: 1em;
  margin: 0;
  padding: 6px 0;
  border-top: 1px solid rgba(200, 204, 209, 0.35);
  border-bottom: 1px solid rgba(200, 204, 209, 0.35);
  font-family: var(--f-mono);
  font-size: 13px;
  font-weight: 400;
  line-height: 1;
  letter-spacing: 0.22em;
}
.wm-groo { font-weight: 500; color: #eef0f2; margin-right: -0.22em; } /* 끝 자간을 빼 낱말 사이를 딱 1em 으로 */
.wm-studio { color: #9aa0a6; margin-right: -0.22em; }
.t-mark { display: inline-block; overflow: hidden; padding-bottom: 0.04em; }
.t-mark .ch { display: inline-block; }
.t-line {
  margin: 12px 0 0;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.08em;
  color: var(--ink-2);
  white-space: nowrap;
}
.hint {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(104px + env(safe-area-inset-bottom));
  margin: 0;
  text-align: center;
  font-size: 12px;
  letter-spacing: 0.16em;
  color: var(--ink-2);
}

/* 잠금 해제 HUD — 눈금자 + 단계 다섯(실제 경계 자리) + 진행선, 숫자 없음 */
.hud {
  position: absolute;
  left: var(--gutter);
  right: var(--gutter);
  bottom: calc(24px + env(safe-area-inset-bottom));
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: end;
  gap: 22px;
  font-size: 11px;
  letter-spacing: 0.08em;
}
.hud-track { position: relative; height: 40px; }
.stages {
  list-style: none;
  margin: 0;
  padding: 0;
  position: absolute;
  inset: 0 0 auto 0;
  height: 16px;
  color: var(--ink-2);
}
.stages li {
  position: absolute;
  left: var(--at, 0);
  top: 0;
  white-space: nowrap;
  overflow: hidden;
  line-height: 16px;
  transition: color 0.3s;
}
.stages li .hc { display: inline-block; }
.stages li.is-done { color: var(--ink-2); }
.stages li[aria-current] { color: var(--glint); }
.scale {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 1px;
  height: 12px;
}
.scale i {
  position: absolute;
  bottom: 0;
  width: 1px;
  height: 4px;
  background: var(--hair-2);
  transform-origin: 50% 100%;
}
.scale i.major { height: 11px; background: var(--ink-2); }
.bar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--hair);
}
.bar i {
  position: absolute;
  inset: 0;
  background: var(--silver);
  transform: scaleX(0);
  transform-origin: 0 50%;
}
.hud-btn {
  appearance: none;
  background: rgba(5, 5, 6, 0.55);
  border: 1px solid var(--btn-line);
  border-radius: 999px;
  min-height: 44px;
  padding: 10px 18px;
  font-size: 12px;
  letter-spacing: 0.06em;
  cursor: pointer;
  white-space: nowrap;
  backdrop-filter: blur(6px);
}
.hud-btn:hover { border-color: var(--silver); }
.hud-skip { color: var(--ink-2); }

/* ── 장면 03 — 금고 안 ─────────────────────────────── */
#inside {
  position: relative;
  z-index: 2; /* 폰 · 정지 판의 세로 줄도 카드 구간 — 어둠 판(z 1) 위로 흐른다 */
  min-height: 100vh;
  padding: clamp(72px, 12vh, 140px) 0 64px;
  background: linear-gradient(to bottom, rgba(5, 5, 6, 0) 0, rgba(5, 5, 6, 0.74) 14%, rgba(5, 5, 6, 0.7) 55%, rgba(5, 5, 6, 0.9) 100%);
}
.inside-head { padding: 0 var(--gutter); max-width: 1200px; margin: 0 auto 36px; }
.eyebrow {
  margin: 0 0 14px;
  font-size: 12px;
  letter-spacing: 0.12em;
  color: var(--ink-2);
}
.inside-head h2 {
  margin: 0;
  font-family: var(--f-voice);
  font-weight: 400;
  font-size: clamp(32px, 4.4vw, 64px);
  line-height: 1.22;
  letter-spacing: -0.01em;
  color: var(--glint);
}

.gallery-note { text-align: center; font-size: 12px; color: var(--ink-2); margin: 14px var(--gutter) 0; }
.gallery-note:empty { display: none; }

/* 바닥글은 모든 쪽이 같은 것 — css/footer.css · js/footer.js */

/* ── 폰 ───────────────────────────────────────────── */
@media (max-width: 640px) {
  .title { top: calc(18px + env(safe-area-inset-top)); }
  .wm { font-size: 12px; padding: 4px 0; }
  .t-line { font-size: 12px; margin-top: 10px; letter-spacing: 0.04em; }
  .hud { grid-template-columns: 1fr auto; gap: 12px 14px; }
  .hud-track { grid-column: 1 / -1; order: -1; }
  .stages { font-size: 11px; letter-spacing: 0.02em; }
  .hud-next { justify-self: start; }
  .hint { bottom: calc(126px + env(safe-area-inset-bottom)); }
}

/* ── 정지 판(움직임 줄이기 · 자동 하향 2단 · WebGL 끊김): 복도 끝 구도 그림 한 장(한 화면) + 001 카드(main.js placeStill), 나머지는 아래 세로 줄.
   그림은 이 판일 때만 받는다(배경 그림이라 다른 때는 요청도 없다). 2단으로 내려갈 때는 3D 가 0.4초에 걸쳐 그림으로 바뀐다 ── */
.still #vault {
  height: 100vh;
  height: 100svh;
  background: var(--void) url("../assets/still_pc.webp") center / cover no-repeat;
}
/* 그림 고르기는 main.js 의 phone 판정과 같게(카드 자리 비율이 그림마다 다르다) */
.phone.still #vault { background-image: url("../assets/still_phone.webp"); }
.still #gl { opacity: 0; transition: opacity 0.4s ease; pointer-events: none; }
.still .title,
.still .hint,
.still .hud,
.still .fx { display: none; }
.still #inside { min-height: 0; padding-top: 24px; }
.no-webgl #gl { display: none; }
/* 폰: 단계 끝 표식(main.js)에 가까이 멈추면 붙는다 — proximity 라 멀면 그냥 지나간다 */
html.snap-y { scroll-snap-type: y proximity; }
.snap-mark { position: absolute; left: 0; top: 0; width: 1px; height: 1px; scroll-snap-align: start; pointer-events: none; }
/* ?debug 화질 점검 글 — 점검 때만 생긴다 */
.debug-box { position: fixed; left: 8px; bottom: calc(8px + env(safe-area-inset-bottom)); z-index: 50; margin: 0; padding: 6px 8px; border-radius: 4px; background: rgba(0, 0, 0, 0.75); color: #e6e8eb; font: 10px/1.45 var(--f-mono); white-space: pre-wrap; max-width: calc(100vw - 16px); pointer-events: none; }
.bench-box { top: calc(8px + env(safe-area-inset-top)); bottom: auto; }
@media (prefers-reduced-motion: reduce) {
  * { scroll-behavior: auto !important; }
}

/* ── 6판(dev) — 단계 이름은 화면에 안 보이고 읽기 도구에만 ── */
.sr-only {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* 3D 위 글은 금속 하이라이트 위에서도 읽히게 그림자 한 겹(디자인 대비 점검 12) */
.title,
.hint,
.hud { text-shadow: 0 0 12px rgba(5, 5, 6, 0.8), 0 1px 2px rgba(5, 5, 6, 0.9); }

/* ── 7판: 여는 법 안내 · 다이얼 손잡이 층 · 흐르는 눈금자 ── */
/* 휠 그림 + 한 줄(마우스: 휠을 내리면 / 터치: 아래로 밀면) — 열기 시작하면 0.3초에 사라진다 */
.cue {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(104px + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  pointer-events: none;
  transition: opacity 0.3s;
  text-shadow: 0 0 12px rgba(5, 5, 6, 0.8);
}
.cue-wheel { position: relative; width: 18px; height: 28px; border: 1px solid var(--silver); border-radius: 9px; }
.cue-wheel i {
  position: absolute;
  left: 50%;
  top: 6px;
  width: 2px;
  height: 5px;
  margin-left: -1px;
  border-radius: 1px;
  background: var(--silver);
  animation: cue-dot 1.6s ease-in-out infinite;
}
@keyframes cue-dot {
  0%, 15% { transform: translateY(0); opacity: 1; }
  65% { transform: translateY(4px); opacity: 0.25; }
  100% { transform: translateY(0); opacity: 1; }
}
.cue-text { font-size: 12px; letter-spacing: 0.04em; color: var(--ink-2); }
.opened .cue { opacity: 0; }
/* 6초 쉬면 한 번: 열기 단추 테두리가 크림으로 숨쉰다 */
.nudge .hud-next { animation: nudge-ring 1.2s ease-in-out 1; }
.nudge .cue-wheel i { animation-duration: 0.8s; }
@keyframes nudge-ring {
  0%, 100% { border-color: var(--btn-line); box-shadow: none; }
  50% { border-color: var(--focus); box-shadow: 0 0 0 3px rgba(243, 238, 231, 0.18); }
}
/* 다이얼 위 투명한 원 — 누르면 열기 · 끌어 돌리면 다이얼이 돈다. 글 · 고리 강조는 두지 않는다(안내는 아래 한 줄뿐) */
.dial-hit {
  position: absolute;
  left: 0;
  top: 0;
  display: none;
  border-radius: 50%;
  cursor: grab;
  touch-action: none;
  z-index: 2;
}
.dial-hit.on { display: block; }
.dial-hit.grabbing { cursor: grabbing; }
/* 눈금자: 작은 눈금은 무늬 한 장 — 다이얼이 돈 각만큼 같은 방향으로 흐른다(1° = 0.5px). 큰 눈금은 단계마다 하나, 끝나면 크림 */
.scale::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 4px;
  background: repeating-linear-gradient(90deg, var(--hair-2) 0 1px, transparent 1px var(--tick-gap, 12px));
  background-position-x: var(--flow, 0px);
}
.scale i.major.lit { background: var(--focus); }
.still .cue,
.still .dial-hit { display: none !important; }
@media (max-width: 640px) {
  .cue { bottom: calc(126px + env(safe-area-inset-bottom)); }
}

/* ── 7판 4단: 안쪽 방 카드 = 앱 진열 판(앱카드 설계 4절 — 모든 프로젝트가 같은 칸) ── */
:root {
  --cream: #f3eee7;
  --hair: rgba(230, 232, 235, 0.12);
  --panel-line: rgba(200, 204, 209, 0.1);
  /* 카드 껍데기(모든 프로젝트 공통) — 금고 문 둘레 금속 #8d9399 에서 한 단 밝은 테 · 흑유리 판 */
  --rim-hi: #9aa0a6;
  --rim-mid: #4b5056;
  --rim-lo: #24272b;
  --rim-foot: #3a3e43;
  --rim-line: rgba(154, 160, 166, 0.45);
  --face-hi: #141619;
  --face-mid: #0d0e10;
  --face-lo: #09090a;
}
/* 앱 아이콘 — 둥근 네모(22.5%), 안쪽 1px 줄 · 그림자는 화면에서. 사진은 틀로만 얼굴 쪽을 보인다(그림은 고치지 않는다) */
.icon {
  --s: 104px;
  position: relative;
  flex: none;
  display: grid;
  place-items: center;
  width: var(--s);
  height: var(--s);
  border-radius: 22.5%;
  overflow: hidden;
  background: #141518;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
  transition: transform 0.24s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.icon::after { content: ""; position: absolute; inset: 0; border-radius: inherit; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08); pointer-events: none; }
.icon.has-img {
  background:
    radial-gradient(60% 60% at 50% 0%, rgba(243, 238, 231, 0.07), transparent 70%),
    linear-gradient(180deg, var(--icon-bg, #15120f), color-mix(in srgb, var(--icon-bg, #15120f) 72%, #000));
}
.icon img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--icon-pos, 50% 40%);
  transform: scale(var(--icon-zoom, 1));
  transform-origin: var(--icon-pos, 50% 40%);
}
.icon.is-empty { box-shadow: none; }
.icon.is-empty::after { box-shadow: inset 0 0 0 1px rgba(200, 204, 209, 0.1); }
.icon-no { font-family: var(--f-mono); font-weight: 500; font-size: calc(var(--s) * 0.22); letter-spacing: 0.04em; color: var(--muted); }

/* 벽감 카드(292px) 껍데기 — 건메탈 테 1px(위가 밝은 금속 그라데이션) · 흑유리 판(아주 옅은 새틴 결 + 위 크림 윗빛) · 모서리 10 · 그림자 두 겹.
   안 여백은 옆만 24(위아래 18) — 카드가 지금보다 높아지면 125% 화면 끝 구도에서 진행 줄에 닿는다. 그림 파일 없이 CSS 만 */
.card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 292px;
  padding: 18px 24px;
  border-radius: 10px;
  border: 1px solid transparent;
  background:
    repeating-linear-gradient(0deg, rgba(255, 255, 255, 0.012) 0 1px, transparent 1px 3px) padding-box,
    radial-gradient(120% 55% at 50% -8%, rgba(243, 238, 231, 0.07), transparent 62%) padding-box,
    linear-gradient(180deg, var(--face-hi) 0%, var(--face-mid) 48%, var(--face-lo) 100%) padding-box,
    linear-gradient(180deg, var(--rim-hi) 0%, var(--rim-mid) 30%, var(--rim-lo) 72%, var(--rim-foot) 100%) border-box;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.6), 0 28px 56px -16px rgba(0, 0, 0, 0.85);
  color: var(--ink);
  text-align: center;
  text-decoration: none;
}
/* 위 테에 크림 빛 한 줄(금고 문틈 빛) — 가운데가 가장 밝고 양 끝 14% 는 비운다 */
.card::before {
  content: "";
  position: absolute;
  top: -1px;
  left: 14%;
  right: 14%;
  height: 1px;
  pointer-events: none;
  background: linear-gradient(90deg, transparent, rgba(243, 238, 231, 0.75), transparent);
}
/* 호버 · 포커스 = 밝은 테 층의 불투명만(카드 · 아이콘 · 그림자는 움직이지 않는다). 테 1px 고리만 남기는 가림(mask) */
.card::after {
  content: "";
  position: absolute;
  inset: -1px;
  padding: 1px;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.24s ease;
  background: linear-gradient(180deg, var(--glint) 0%, var(--rim-hi) 32%, var(--rim-mid) 74%, #8d9399 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
}
.card:has(:focus-visible)::after { opacity: 1; }
/* 키보드 포커스: 큰 링크 · 자세히 어느 쪽에 가도 카드 둘레에 크림 2px. 마우스로 누른 뒤에는 남지 않게 :focus-visible 로 고른다 */
.card:has(:focus-visible) { outline: 2px solid var(--focus); outline-offset: 4px; }
/* 테 각인 번호 — 왼쪽 위 안쪽, ⑥ 머리 · 벽감 번호판과 같은 모노. 읽어 주지 않는다(번호는 이름 링크가 말한다) */
.card-serial { position: absolute; top: 13px; left: 15px; font: 500 10px/1 var(--f-mono); letter-spacing: 0.22em; color: #8a9096; pointer-events: none; }
/* 큰 누름 — 이름의 링크를 카드 전체로 펼친다(::after). 카드의 포커스 고리는 위 :has, 목록 줄은 펼친 자리에 크림 2px */
.card-link, .lrow-link { color: inherit; text-decoration: none; outline: none; }
.card-link::after, .lrow-link::after { content: ""; position: absolute; inset: 0; z-index: 1; }
.card-link::after { border-radius: 10px; }
.lrow-link:focus-visible::after { outline: 2px solid var(--focus); outline-offset: 3px; }
/* 작은 링크 · 단추는 펼친 링크 위에(누르는 자리 44px) */
.card-more, .lrow-more, .card-shot-fold { position: relative; z-index: 2; }
.card-more {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin: 4px 0 -12px;
  padding: 0 12px;
  font-size: 12px;
  color: var(--ink-2);
  text-decoration: none;
}
.card-more:hover { color: var(--ink); }
.card-ext { position: absolute; top: 14px; right: 16px; font-size: 12px; color: var(--ink-2); opacity: 0; transition: opacity 0.2s; }
/* 호버: 테 빛 · 오른쪽 위 ↗ — 둘 다 불투명만. 들어 올림 · 아이콘 키움은 두지 않는다(60fps · 벽감 자리 그대로) */
@media (hover: hover) {
  .card.is-live:hover::after { opacity: 1; }
  .card.is-live:hover .card-ext { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) { .card::after { transition: none; } }
.card-name { margin: 14px 0 0; font-family: var(--f-display); font-weight: 400; font-size: 26px; line-height: 1; color: var(--glint); }
.card-name-ko { margin: 4px 0 0; font-size: 12px; font-weight: 500; color: var(--ink-2); }
.card-tags { display: flex; gap: 6px; justify-content: center; margin-top: 8px; }
.tag {
  display: inline-flex;
  align-items: center;
  height: 22px;
  padding: 0 9px;
  border: 1px solid rgba(163, 169, 176, 0.5);
  border-radius: 999px;
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-2);
  white-space: nowrap;
}
.lamp { width: 6px; height: 6px; margin-right: 6px; border-radius: 50%; border: 1px solid var(--ink-2); box-sizing: border-box; }
[data-status="ACTIVE"] .lamp { background: var(--cream); border-color: var(--cream); box-shadow: 0 0 6px rgba(243, 238, 231, 0.7); }
.card .tag { border-color: var(--rim-line); background: rgba(255, 255, 255, 0.015); } /* 꼬리표 테를 카드 테 색에 */
.card-line { margin: 10px 0 0; font-size: 13px; line-height: 1.5; color: var(--silver); }
.card-fig { align-self: stretch; display: flex; flex-direction: column; align-items: center; margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--hair); }
/* 카드의 숫자 칸 = 계기판 창: 한 단 들어간 판(테두리 두 줄 — 위 검정 · 아래 흰 5%, 그림자 아님) + 10px 위에 양 끝이 사라지는 금속 줄 */
.card > .card-fig {
  position: relative;
  margin-top: 23px;
  padding: 6px 0 5px;
  border-radius: 6px;
  border-top: 1px solid rgba(0, 0, 0, 0.65);
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
  background: rgba(0, 0, 0, 0.34);
}
.card > .card-fig::before { content: ""; position: absolute; top: -12px; left: 0; right: 0; height: 1px; background: linear-gradient(90deg, transparent, rgba(154, 160, 166, 0.38), transparent); }
.card-led { height: 40px; }
.card-led .led { display: inline-flex; gap: 3px; align-items: flex-end; transform: skewX(-6deg); transform-origin: 50% 100%; }
.card-led .led svg { display: block; height: 40px; width: auto; overflow: visible; }
.fig-l1 { margin: 6px 0 0; font-size: 12px; line-height: 1.5; color: var(--silver); }
.fig-l2 { margin: 0; font-size: 12px; line-height: 1.5; color: var(--ink-2); }
.fig-l2:empty { display: none; }
/* 숫자 옆 출처 조각 — 11px --ink-2. 짧은 글이 없을 때의 '출처 →' 는 펼친 큰 링크 위에(누르는 자리) */
.fig-src { font-size: 11px; color: var(--ink-2); }
.fig-src-link { position: relative; z-index: 2; text-decoration: none; }
.fig-src-link:hover { color: var(--ink); }
.lrow-right small.fig-src { display: block; }
.card-shot { display: block; align-self: stretch; margin-top: 14px; aspect-ratio: 16 / 10; border-radius: 6px; border: 1px solid rgba(154, 160, 166, 0.22); overflow: hidden; background: #0c0a09; }
.card-shot img { display: block; width: 100%; height: 100%; object-fit: cover; }
.card-shot-fold { display: none; min-height: 44px; margin-top: 4px; padding: 0 12px; border: 0; background: none; font: inherit; font-size: 12px; color: var(--ink-2); cursor: pointer; }
.card.shot-folded .card-shot,
.deck-wrap.shot-folded .card-shot { display: none; }
.card.shot-folded .card-shot-fold,
.deck-wrap.shot-folded .card-shot-fold { display: inline-flex; align-items: center; }
.card-notice { margin: 12px 0 0; font-size: 12px; line-height: 1.5; color: var(--ink-2); }

/* 컴퓨터 3D: 벽감 자리에 붙는 층 — 고정 구간 안 */
.niche-layer { position: absolute; inset: 0; pointer-events: none; z-index: 3; }
.niche-layer > * { position: absolute; left: 0; top: 0; opacity: 0; visibility: hidden; transition: opacity 0.4s, visibility 0s 0.4s; }
.niche-layer > .shown { opacity: calc(var(--niche-in, 0) * var(--o, 1)); visibility: visible; pointer-events: auto; transition: opacity 0.4s; } /* --o: 복도 걷기에서 지금 선 벽감과의 거리 */
/* 빈 벽감 — 번호 아이콘 80(어둡게 .7) + '빈 자리'. 멀수록 아이콘만 작아진다(--k, main.js) */
.niche-empty { display: flex; flex-direction: column; align-items: center; gap: 12px; }
.niche-empty .icon { opacity: 0.7; scale: var(--k, 1); margin: calc((var(--k, 1) - 1) * 40px) 0; }
.niche-empty p { margin: 0; font-size: 12px; color: var(--ink-2); text-shadow: 0 0 12px rgba(5, 5, 6, 0.8); }
/* 안쪽 방 머리(앱카드 설계 1 · 2절): ⑥ 2단 꼴 + 24px 아래 두 줄. 모서리 ⑤ 는 여는 동안만이라 머리가 서면 진다 */
.niche-head {
  position: absolute;
  left: var(--gutter);
  top: calc(32px + env(safe-area-inset-top)); /* 머리 위 여백 32(규격) */
  opacity: var(--niche-in, 0);
  pointer-events: none;
  text-shadow: 0 0 16px rgba(5, 5, 6, 0.85);
  isolation: isolate; /* 뒤 어둠(::before)이 머리 안에서만 글자 뒤로 — 캔버스 뒤로 빠지지 않게 */
}
/* 머리 뒤 부드러운 어둠(7판 설계 3-3 '천장 빛줄') — 빛줄은 옮기지 않고 머리 글자 뒤에서만 가라앉힌다. 걷기 멈춤 · 화면 비율마다 빛줄 자리가
   달라 머리 쪽에서 막는다. 머리 상자 가운데에 중심을 둔 타원(상자의 2.2배) — 글자 상자 네 귀퉁이까지 진한 판(.78) 안이고 끝은 0 으로 녹는다.
   불투명은 머리 것을 따라 같이 나타나고 사라진다 · 누름을 막지 않는다 · 카드(.niche-layer z 3)는 그 위 */
.niche-head::before {
  content: "";
  position: absolute;
  inset: -60%;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(farthest-side, rgba(4, 4, 5, 0.78) 0%, rgba(4, 4, 5, 0.78) 64%, rgba(4, 4, 5, 0.66) 74%, rgba(4, 4, 5, 0.44) 83%, rgba(4, 4, 5, 0.2) 91%, rgba(4, 4, 5, 0.06) 97%, rgba(4, 4, 5, 0) 100%);
}
.title { opacity: calc(1 - var(--niche-in, 0)); }
.brand6 { display: flex; flex-direction: column; align-items: flex-start; margin: 0; font-size: 32px; line-height: 1; }
.b6-en { font-family: var(--f-mono); font-weight: 700; letter-spacing: 0.02em; color: var(--glint); }
.b6-ko { margin-top: 0.25em; font-family: var(--f-ui); font-size: 0.4em; font-weight: 500; letter-spacing: 0.3em; color: var(--ink-2); }
/* 높이가 낮은 컴퓨터 화면(1366×768 · 1280×800)에서는 벽감 카드(높이 ~560)를 한 단 줄인다 — main.js 가 자리 transform 끝에 scale(var(--cs)) 를 붙인다
   (scale 속성은 transform 보다 먼저 적용돼 자리 이동까지 줄여 카드가 벽감에서 비켜났다) */
/* --lift: 카드를 벽감 가운데에서 위로 띄운다 — 진행 줄 눈금과 8px · 바닥선과 10px 이상(7판 대조 17번: 1366×768 에서 눈금에 4px 걸렸다).
   더 줄이면(scale) 125% 화면 글자가 8px 아래로 내려가 띄우기로 */
@media (max-height: 860px) { html:not(.phone) .niche-layer > .card { --cs: 0.9; --lift: 12px; } }
@media (max-height: 740px) { html:not(.phone) .niche-layer > .card { --cs: 0.8; --lift: 8px; } }
/* 아주 낮은 컴퓨터 화면(1366×768 을 125% 로 키운 1093×614 등) — 카드 · 머리를 한 단 더 줄여 머리 아래와 카드 윗변이 닿지 않게.
   .68 — .7 에서는 카드 아랫변과 진행 줄 틈이 4~5px 라 마우스 시차(가로)까지 더하면 8px 를 못 지켰다 */
@media (max-height: 660px) {
  html:not(.phone) .niche-layer > .card { --cs: 0.68; --lift: 8px; }
  .brand6 { font-size: 26px; }
  .niche-lines { margin-top: 16px; font-size: 24px; }
}
/* 높이가 낮은 화면에서는 벽감 카드 윗변에 닿지 않게 머리 두 줄도 화면 높이로 줄인다 */
.niche-lines { margin: 24px 0 0; font-family: var(--f-voice); font-weight: 400; font-size: clamp(28px, min(4vw, 5vh), 48px); line-height: 1.2; color: var(--glint); }
.phone .brand6 { font-size: 24px; }
/* 폰: 3D 는 입구 정면에서 멈추고 001 카드는 아래쪽 가운데에 평평하게(정지 그림 위에서도) */
.phone .niche-layer > .card { left: 50%; top: auto; bottom: calc(24px + env(safe-area-inset-bottom)); transform: translateX(-50%) !important; width: min(300px, calc(100vw - 48px)); }
/* 폰 카드 — 같은 껍데기, 옆 여백 20 · 멀리 그림자 한 단 얕게. 폰은 카드 폭이 그대로라(그림 칸이 안 줄어) 위아래 18 이면 숫자 창만큼 3px 높아진다 → 16 */
.phone .card { padding: 16px 20px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.6), 0 18px 36px -12px rgba(0, 0, 0, 0.8); }
/* 낮은 폰 — 카드 윗변이 머리 두 줄 아래 16px 를 지키게 main.js(fitPhoneCard)가 한 단씩 건다(7판 설계 3-3: 머리 두 줄 줄이기 → 카드 내리기) */
.phone.head-tight .niche-lines { margin-top: 16px; font-size: 24px; }
.phone .niche-layer > .card.card-low,
.phone .niche-layer > .deck-wrap.card-low { bottom: calc(12px + env(safe-area-inset-bottom)); }
.phone .card.card-compact .icon,
.phone .deck-wrap.card-compact .icon { --s: 80px !important; }
/* 아주 낮은 폰: 끝 구도에서는 카드를 빼고(머리 · 복도만), 같은 카드(묶음)가 아래 세로 줄 맨 앞에 선다 */
.flow-card { display: none; }
.phone.card-flow .niche-layer > .card,
.phone.card-flow .niche-layer > .deck-wrap { display: none; }
.phone.card-flow .card-list > .flow-card { display: flex; width: min(300px, 100%); margin: 0 auto 24px; }
/* 묶음은 목록 폭에 묶는다(늘이기) — 가운데 맞춤 세로 줄에서 폭 auto 는 카드 폭의 합(728)이 되어 쪽을 옆으로 넓혔다(390×664 scrollWidth 559) */
.phone.card-flow .card-list > .deck-wrap.flow-card { display: block; align-self: stretch; width: auto; min-width: 0; margin: 0 calc(-1 * var(--gutter)) 24px; }

/* ── 폰 가로 스와이프 묶음(앱카드 설계 6-1) — 프로젝트 둘 이상. 카드 폭 = 화면 − 64(양옆 32: 이웃 카드 20 보임 + 사이 12).
   넘김은 scroll-snap 만(한 번에 한 장 · 끝 튕김은 브라우저 것만), 높이는 가장 큰 카드에 맞추고 '자세히 →' 는 맨 아래 ── */
.phone .niche-layer > .deck-wrap { left: 0; right: 0; top: auto; bottom: calc(24px + env(safe-area-inset-bottom)); transform: none !important; }
.deck {
  position: relative;
  display: flex;
  align-items: stretch;
  gap: 12px;
  padding: 8px 32px 28px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: 32px;
  scrollbar-width: none;
}
.deck::-webkit-scrollbar { display: none; }
.deck:focus-visible { outline: 2px solid var(--focus); outline-offset: -2px; border-radius: 12px; }
.deck > .card { flex: 0 0 calc(100vw - 64px); width: auto; scroll-snap-align: center; scroll-snap-stop: always; }
.deck > .card .card-more { margin-top: auto; }
/* 짧은 카드(자세히가 없는 BUILDING 등)는 마지막 줄(면책)을 아랫변으로 — 늘어난 높이가 면책 아래 빈 띠로 남지 않게.
   이웃에 '자세히 →' 가 있으면 그 자리(44 − 12)만큼 띄워 카드끼리 면책 줄 높이를 맞춘다 */
.deck > .card > .card-notice:last-child { margin-top: auto; padding-top: 12px; }
.deck:has(.card-more) > .card > .card-notice:last-child { margin-bottom: 32px; }
.deck-dots { display: flex; justify-content: center; margin-top: -8px; }
.deck-dots button { display: flex; align-items: center; justify-content: center; width: 24px; height: 44px; padding: 0; border: 0; background: none; cursor: pointer; }
.deck-dots i { display: block; width: 6px; height: 6px; border-radius: 50%; background: var(--muted); transition: background 0.2s, transform 0.2s; }
.deck-dots button[aria-current="true"] i { background: var(--cream); transform: scale(1.25); }
.deck-dots button:focus-visible { outline: 2px solid var(--focus); outline-offset: -10px; border-radius: 12px; }
/* 낮은 폰 묶음(앱카드 설계 6-1 '낮은 폰') — 3-3 ①~④ 뒤에 묶음에만 세 단, main.js(fitPhoneCard)가 한 단씩 건다.
   ⑤ 점 줄 낮춤: 누르는 자리 24×24 · 카드 ↔ 점 20 → 8 · 묶음 위 8 → 0(−40) ⑥ 아이콘 80 → 64(−16)
   ⑦ 카드 안 칸 사이 14 → 10(아이콘↔이름 · 한 줄↔숫자 · 숫자↔화면 그림, 접혔으면 그 단추) · 12 → 8(면책 위)(−16) */
.phone .deck-wrap.dots-tight .deck { padding-top: 0; }
.phone .deck-wrap.dots-tight .deck-dots { margin-top: -20px; }
.phone .deck-wrap.dots-tight .deck-dots button { height: 24px; }
.phone .deck-wrap.dots-tight .deck-dots button:focus-visible { outline-offset: -2px; }
.phone .deck-wrap.icon-small .icon { --s: 64px !important; }
.phone .deck-wrap.gaps-tight .card-name { margin-top: 10px; }
.phone .deck-wrap.gaps-tight .card > .card-fig { margin-top: 19px; }
.phone .deck-wrap.gaps-tight .card > .card-fig::before { top: -10px; }
.phone .deck-wrap.gaps-tight .card-shot { margin-top: 10px; }
.phone .deck-wrap.gaps-tight .card-shot-fold { margin-top: 0; }
.phone .deck-wrap.gaps-tight .card-notice { margin-top: 8px; }
.phone .deck-wrap.gaps-tight .card > .card-notice:last-child { margin-top: auto; padding-top: 8px; }
/* 움직임 줄이기: 세로로 쌓는다(맞춤 · 점 없음) */
@media (prefers-reduced-motion: reduce) {
  .deck { flex-direction: column; gap: 16px; padding: 8px 16px 16px; overflow: visible; scroll-snap-type: none; }
  .deck > .card { flex: none; width: 100%; }
  .deck:has(.card-more) > .card > .card-notice:last-child { margin-bottom: 0; } /* 세로로 쌓으면 높이를 맞출 이웃이 없다 */
  .deck-dots { display: none; }
}
/* 폰: 카드가 서면 아래 눈금자 · 단추는 걷는다(카드 자리 — 할 일은 끝났고 아래로 밀면 세로 줄) */
.hud { transition: opacity 0.4s, visibility 0s; }
/* 고정이 풀리면 눈금자 · 단추를 200ms 에 감춘다(위로 다시 들어가면 보임) — 이어서는 그냥 내리면 카드 구간 · 바닥글 */
.pin-done .hud,
.phone.niche-on .hud { opacity: 0; visibility: hidden; transition: opacity 0.2s, visibility 0s 0.2s; } /* 폰은 카드가 서면 바로(카드가 화면 아래쪽을 차지한다) */
/* 카드 구간 끝 40% 의 어둠 판 — 바닥글이 검은 바탕 위에 오도록(배경 그림만 덮고 머리 · 카드는 그 위) */
/* 바닥글 윗변(--ft) 위 화면 높이 40% 는 배경이 --void 로 녹아 바닥글과 이어진다 — 곧은 가로 경계 없이(7판 대조 F1).
   그 위에 고정 뒤 끝 40% 의 고른 어둠(--dark). 둘 다 배경만 덮고 머리 · 카드(#vault z 2)는 그 위 */
.stage-dim {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(to bottom, rgba(5, 5, 6, 0) calc(var(--ft, 200vh) - 40vh), #050506 var(--ft, 200vh)),
    rgba(5, 5, 6, var(--dark, 0));
}
/* 카드 구간 끝 = 카드 아랫변 + 아래 여백(컴퓨터 96 · 폰 64) — main.js 가 바닥글 위 여백(음수일 수 있음)을 그 자리에서 맞춘다 */
/* 컴퓨터 3D 첫 화면의 바닥글은 한 화면(가운데 맞춤) — 맨 아래에서 카드가 화면 위로 반쯤 잘린 채 남지 않게 */
footer.gfoot.is-stage { display: flex; flex-direction: column; justify-content: center; min-height: 100vh; min-height: 100svh; }
/* 세로 줄은 첫 화면 카드(001)의 이어짐이라 머리 글은 화면 읽기에만 — 보이는 머리 글은 첫 화면 왼쪽 위 */
#inside .inside-head { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* 세로 줄(폰 · 정지 판) — 컴퓨터 3D 에서는 #inside 를 숨긴다(복도가 그 자리) */
html:not(.list-mode) #inside { display: none; }
.card-list { display: flex; flex-direction: column; align-items: center; padding: 0 var(--gutter); }
/* 목록 줄(작게, 앱카드 설계 4-2) — 아이콘 64 · 줄 높이 96 · 줄 사이 1px. 줄 전체가 큰 링크(이름의 링크를 펼침) */
.lrow {
  position: relative;
  display: flex;
  align-items: center;
  gap: 16px;
  width: min(720px, 100%);
  min-height: 96px;
  padding: 16px;
  border-bottom: 1px solid var(--hair);
  color: inherit;
  text-align: left;
  text-decoration: none;
}
.lrow-mid { flex: 1; min-width: 0; }
.lrow-t { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.lrow-name { font-family: var(--f-display); font-size: 20px; line-height: 1; color: var(--glint); }
.lrow-ko { font-size: 12px; font-weight: 500; color: var(--ink-2); }
.lrow-line { margin: 6px 0; font-size: 13px; line-height: 1.5; color: var(--silver); }
.lrow .card-tags { justify-content: flex-start; margin: 0; }
.lrow-right { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
.lrow-right .card-fig { align-self: auto; align-items: flex-end; margin: 0; padding: 0; border: 0; }
.lrow-right .card-led { height: 24px; }
.lrow-right .card-led .led svg { height: 24px; }
.lrow-right .fig-l1 { margin: 2px 0 0; font-size: 11px; color: var(--ink-2); }
.lrow-more { display: inline-flex; align-items: center; min-height: 44px; font-size: 13px; color: var(--ink); text-decoration: none; }
.lrow-more:hover { color: var(--glint); }
/* 빈 자리 줄(폰 목록 끝) — 번호 아이콘 40 + 번호 + 글 */
.erow { display: flex; align-items: center; gap: 12px; width: min(720px, 100%); min-height: 56px; padding: 8px 16px; border-bottom: 1px solid var(--hair); font-size: 12px; color: var(--ink-2); }
.empty-no { font-family: var(--f-mono); font-size: 11px; font-weight: 500; letter-spacing: 0.14em; }

/* ── 첫 그림: 닫힌 금고 정지 판(도입 모션은 뺐다 — 누구나 같은 첫 화면). 3D 와 같은 구도 — 가로 화면은 높이에 맞춤(금고 지름이
   화면 높이를 따른다), 세로 화면(비율 .99 아래)은 폭에 맞춤(vault.js fitDistance 와 같은 갈림). 3D 가 다 구워져 첫 장면을 그리면 걷는다.
   가장자리 어둡게는 3D 색 고르기(grade)와 같은 꼴을 여기서 얹는다 — 그림판 비율에 매인 값이라 그림에는 굽지 않았다(tools/boot-still.mjs) ── */
.boot-still { position: absolute; inset: 0; background: #040405 url("../assets/boot_wide.webp") 50% 50% / auto 100% no-repeat; pointer-events: none; transition: opacity 0.25s, visibility 0s 0.25s; }
.boot-still::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 92% 108.24% at 50% 50%, rgba(0, 0, 0, 0) 30.4%, rgba(0, 0, 0, 0.021) 40%, rgba(0, 0, 0, 0.077) 50%, rgba(0, 0, 0, 0.155) 60%, rgba(0, 0, 0, 0.241) 70%, rgba(0, 0, 0, 0.32) 80%, rgba(0, 0, 0, 0.378) 90%, rgba(0, 0, 0, 0.4) 100%);
}
@media (max-aspect-ratio: 99/100) { .boot-still { background-image: url("../assets/boot_tall.webp"); background-size: 100% auto; } }
.gl-on .boot-still, .still .boot-still, .no-webgl .boot-still { opacity: 0; visibility: hidden; }
