/* ============================================================
   vitaminwoo — 디자인 토큰
   ============================================================ */
:root {
  --bg: #0b0c10;
  --bg-raised: #121319;
  --ink: #f1efe7;
  --ink-muted: #9c9a92;
  --hairline: rgba(255, 255, 255, 0.08);
  --hairline-strong: rgba(255, 255, 255, 0.16);

  --motion: #e8a33d;
  --ai: #4fe0c4;
  --apps: #ff7a59;
  --violet: #a760ff;

  --motion-rgb: 232, 163, 61;
  --ai-rgb: 79, 224, 196;
  --apps-rgb: 255, 122, 89;
  --violet-rgb: 167, 96, 255;
  --ink-rgb: 241, 239, 231; /* --ink의 rgba() 합성용 짝 — 카테고리 없는 슬롯(media 등) 글로우에 사용 */

  /* ── Home 쌓임 순서 (3D 로비 리뉴얼 대비) ─────────────────────────
     예전에는 본문(.ticket-entry)에 z-index가 없어(auto) 고정 배경 레이어(1)
     아래에 놓이는 것이 "우연히" 성립했다 — 배경 캔버스가 거의 투명해서
     문제가 드러나지 않았을 뿐이다. 불투명한 WebGL 캔버스를 그 자리에 넣는
     순간 본문이 통째로 가려지므로, 3D 캔버스가 들어갈 자리를 본문보다
     아래(--z-home-backdrop)에 미리 비워 두고 상하 관계를 명시한다.
     값은 현재 화면과 동일하게 유지한다(순서 변화 없음).
     본문 내부의 z-index(티켓 스탬프 2, 스윕 5 등)는 .ticket-card의
     isolation:isolate 안에 갇혀 있어 이 층위로 새어 나오지 않는다.
     토큰화하지 않은 상위 레이어(다른 페이지와 공유하므로 리터럴 유지):
     nav 100 · 오버레이 패널 200/201 · 전환 페이드 998/999 ·
     티켓 디졸브 캔버스 1000 · 커스텀 커서 9999 */
  --z-home-backdrop: -1; /* 예약: 3D 로비 캔버스(P1) — 본문 아래 */
  --z-home-content: 0; /* 본문 <main class="ticket-entry"> */
  --z-home-fx: 1; /* 앰비언트 그라디언트 · home-fx 캔버스 · 티켓 materialize 캔버스 */

  /* "Noto Sans JP"는 일본어(히라가나/가타카나/한자) 폴백 — Fraunces/Inter/
     JetBrains Mono가 지원하지 않는 글자만 이 폰트로 자연스럽게 이어받는다.
     라틴 문자는 계속 원래 폰트가 그리므로 기존 디자인 톤에 영향이 없다. */
  --font-display: "Fraunces", "Noto Sans JP", "Georgia", serif;
  --font-body: "Inter", "Noto Sans JP", -apple-system, sans-serif;
  --font-mono: "JetBrains Mono", "Noto Sans JP", monospace;

  --container: 1160px;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

img, video { max-width: 100%; display: block; }

a { color: inherit; text-decoration: none; }

/* 안드로이드 크롬의 탭 회색 플래시 제거 — 인터랙티브 요소 전반. 예전엔
   3D 갤러리 가로 모드 게이트(game.css) 한 곳에만 있어 나머지 버튼/링크에서
   플래시가 남았다. 탭 피드백은 각 요소의 :active/전환이 담당한다. */
a, button, input, textarea, select, [role="button"] {
  -webkit-tap-highlight-color: transparent;
}

/* ── 공통 인터랙션 상태 — focus-visible 글로우 + :active 눌림 ──────────
   :where()로 특정도를 0으로 유지한다 — 요소별로 이미 정의된 상태(폼 입력의
   focus 글로우, 하트 버튼 scale 0.92, Behance/SNS 버튼)와 base 규칙이 항상
   이기므로 기존 구현과 충돌하지 않는다.
   - focus-visible: 방명록/코멘트 입력에 먼저 적용한 문법(은은한 글로우)의
     승격판. UA 기본 아웃라인을 글로우로 대체한다. 카테고리색이 있는
     요소([data-cat] 조상 포함)는 그 색, 없으면 앰버(--motion).
   - active: 클릭 즉답 — 탭 하이라이트를 제거했으므로(위) 모바일 눌림
     피드백은 이 규칙이 담당한다. base에 transform이 있는 요소(캐러셀
     화살표의 translateY 등)와 인라인 요소에는 적용되지 않는다 — 그런
     요소는 자기 규칙에서 처리한다(.carousel-arrow:active 참고). */
[data-cat="motion"] { --focus-glow-rgb: var(--motion-rgb); }
[data-cat="ai"] { --focus-glow-rgb: var(--ai-rgb); }
[data-cat="apps"] { --focus-glow-rgb: var(--apps-rgb); }
[data-cat="violet"] { --focus-glow-rgb: var(--violet-rgb); }

:where(a, button, [role="button"], select, summary):focus-visible {
  outline: none;
  box-shadow: 0 0 14px 1px rgba(var(--focus-glow-rgb, var(--motion-rgb)), 0.22);
}

:where(a, button, [role="button"]):active {
  transform: scale(0.94);
  transition: transform 0.12s ease;
}

.wrap {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 32px;
}

/* ── 네비게이션 ───────────────────────────────────────────── */
.nav {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(11, 12, 16, 0.85);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--hairline);
}

.nav .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 72px;
}

/* 로고 — 보라 M+H 모노그램(assets/logo-mark.svg, 30px) + 작은 워드마크. 워드마크를 빼려면 .nav-logo--mark-only(2026-09-27 로고 교체) */
.nav-logo {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1;
}
.nav-logo-mark { display: block; width: 30px; height: 30px; }
.nav-logo--mark-only .nav-logo-word { display: none; }

.nav-links {
  display: flex;
  gap: 36px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.nav-links a,
.nav-links button.nav-link-btn {
  font-size: 14px;
  font-family: var(--font-mono);
  color: var(--ink-muted);
  transition: color 0.2s ease;
  position: relative;
}

.nav-links button.nav-link-btn {
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
}

.nav-links a.active { color: var(--ink); }

/* 호버 규칙은 hover:hover 게이트 안에만 — 터치 기기에서 탭 후 눌린 채
   남는 sticky hover 방지(사이트 3중 게이트 문법의 CSS 층). 이하 동일. */
@media (hover: hover) {
  .nav-links a:hover,
  .nav-links button.nav-link-btn:hover {
    color: var(--ink);
  }
}

.nav-links a.active::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -24px;
  width: 100%;
  height: 2px;
  background: var(--ink);
}

/* ── 언어 선택(KOR / ENG / JPN) — 네비게이션 우측 끝 ───────────────────
   "나열"이 아니라 "고르는 것"으로 읽히는 분절 컨트롤: 헤어라인 알약 안에 셋이 들어가고
   활성 언어만 잉크로 채워진다(나머지는 muted). 마크업은 i18n.js가 [data-lang-toggle]에
   그리므로 전 페이지가 같은 UI를 쓴다. */
/* P31(2026-09-23): 분절 컨트롤 → 현재 언어 2자(KR/EN/JP) 알약 + 아래 드롭다운(3언어, 현재 ✓). i18n.js renderLangToggles가 그린다. */
.nav-lang-toggle {
  position: relative;
  display: inline-flex;
  align-items: center;
}
.nav-lang-pill {
  appearance: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 0;
  padding: 5px 10px 5px 12px;
  border: 1px solid var(--hairline-strong);
  border-radius: 999px;
  background: color-mix(in srgb, var(--bg) 55%, transparent);
  font-family: var(--font-mono);
  font-size: 11px;
  line-height: 1;
  letter-spacing: 0.1em;
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
  transition: color 0.2s ease, background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
}
.nav-lang-pill-chev { width: 10px; height: 6px; color: var(--ink-muted); transition: transform 0.2s cubic-bezier(0.22, 1, 0.36, 1), color 0.2s ease; }
@media (hover: hover) {
  .nav-lang-pill:hover { border-color: var(--ink); background: var(--hairline); }
  .nav-lang-pill:hover .nav-lang-pill-chev { color: var(--ink); }
}
.nav-lang-pill:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--bg), 0 0 0 3.5px var(--ink); }
.nav-lang-toggle.is-open .nav-lang-pill { border-color: var(--ink); }
.nav-lang-toggle.is-open .nav-lang-pill-chev { transform: rotate(180deg); color: var(--ink); }
/* 드롭다운 — 알약 아래 8px, 시그니처 커브 0.2s(위에서 내려오며 펼쳐진다). 닫힘: visibility로 포커스/클릭까지 막는다 */
.nav-lang-list {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 200;
  min-width: 150px;
  margin: 0;
  padding: 6px;
  list-style: none;
  border: 1px solid var(--hairline-strong);
  border-radius: 14px;
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: blur(10px);
  box-shadow: 0 14px 34px -14px rgba(0, 0, 0, 0.6);
  transform-origin: top right;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px) scale(0.96);
  transition: opacity 0.2s cubic-bezier(0.22, 1, 0.36, 1), transform 0.2s cubic-bezier(0.22, 1, 0.36, 1), visibility 0.2s;
}
.nav-lang-toggle.is-open .nav-lang-list { opacity: 1; visibility: visible; transform: translateY(0) scale(1); }
.nav-lang-option {
  display: grid;
  grid-template-columns: 26px 1fr 14px;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: 9px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  color: var(--ink-muted);
  cursor: pointer;
  transition: color 0.15s ease, background-color 0.15s ease;
}
.nav-lang-option-code { font-weight: 600; letter-spacing: 0.1em; }
.nav-lang-option-name { font-family: var(--font-body); font-size: 12px; letter-spacing: 0; }
.nav-lang-option-check { opacity: 0; font-size: 11px; color: var(--ink); transition: opacity 0.15s ease; }
.nav-lang-option.is-active { color: var(--ink); }
.nav-lang-option.is-active .nav-lang-option-check { opacity: 1; }
@media (hover: hover) { .nav-lang-option:hover { color: var(--ink); background: var(--hairline); } }
.nav-lang-option:focus-visible { outline: none; color: var(--ink); background: var(--hairline); box-shadow: inset 0 0 0 1px var(--ink); }
@media (prefers-reduced-motion: reduce) { .nav-lang-list, .nav-lang-pill-chev { transition-duration: 0.01ms; } }
/* no-JS 폴백 마크업(정적 버튼)용 최소 스타일 */
.nav-lang-btn { appearance: none; background: none; border: none; padding: 4px 8px; font-family: var(--font-mono); font-size: 11px; color: var(--ink-muted); cursor: pointer; }
.nav-lang-btn.is-active { color: var(--ink); }

/* 옛 구분자("|") — i18n.js가 다시 그리면 사라지지만 no-JS 폴백 마크업을 위해 남겨둔다 */
.nav-lang-sep {
  color: var(--hairline-strong);
  font-size: 11px;
}

/* ── 언어 전환 크로스페이드(0.2s) — i18n.js가 <html>에 잠깐 붙이는 클래스 ──
   문구 자리만 0.1초 사라졌다가 바뀐 글자로 0.1초 나타난다. transition이 아니라 animation인
   이유: 요소가 이미 갖고 있는 opacity transition(관문 라벨 등)을 덮어쓰지 않기 위해서다. */
html.i18n-fade-out [data-i18n],
html.i18n-fade-out [data-i18n-html],
html.i18n-fade-out .about-lang-panel {
  animation: i18n-fade-out 0.1s ease forwards;
}
html.i18n-fade-in [data-i18n],
html.i18n-fade-in [data-i18n-html],
html.i18n-fade-in .about-lang-panel {
  animation: i18n-fade-in 0.1s ease both;
}
@keyframes i18n-fade-out { to { opacity: 0; } }
@keyframes i18n-fade-in { from { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  html.i18n-fade-out [data-i18n],
  html.i18n-fade-out [data-i18n-html],
  html.i18n-fade-out .about-lang-panel,
  html.i18n-fade-in [data-i18n],
  html.i18n-fade-in [data-i18n-html],
  html.i18n-fade-in .about-lang-panel { animation: none; }
}

/* ── 히어로 ──────────────────────────────────────────────── */
.hero {
  padding: 96px 0 64px;
}

.hero-eyebrow {
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--ink-muted);
  letter-spacing: 0.04em;
  margin: 0 0 20px;
}

.hero-title {
  font-family: var(--font-display);
  font-size: clamp(40px, 6vw, 76px);
  line-height: 1.05;
  letter-spacing: -0.02em;
  margin: 0 0 24px;
  max-width: 820px;
}

.hero-title em {
  font-style: italic;
  color: var(--ink-muted);
}

.hero-desc {
  font-size: 18px;
  color: var(--ink-muted);
  max-width: 560px;
  margin: 0;
}

/* ── 3D 캐러셀 (시그니처 요소) ───────────────────────────── */
.carousel-section {
  padding: 40px 0 100px;
  overflow: hidden;
  scroll-margin-top: 88px;
}

/* work-grid.html은 이제 이 캐러셀 하나가 페이지 전체다 — 남은 뷰포트
   높이(고정 네비 72px 제외)를 정확히 채워 페이지 자체가 스크롤되지
   않게 하고, 내부 콘텐츠를 수직 중앙 정렬한다. */
.carousel-section--top {
  height: calc(100vh - 72px);
  display: flex;
  align-items: center;
  padding-top: 0;
  padding-bottom: 0;
}

/* v5.5: 캐러셀 트랙을 화면 전체 폭으로 — .wrap의 컨테이너 최대폭/좌우 패딩을
   해제해 카드 열이 뷰포트 가장자리까지 뻗는다(양끝 카드가 화면에 살짝 걸침).
   work-grid.js도 같은 목적으로 가시 범위를 ±2 → ±3장으로 넓혔다. */
.carousel-section--top .wrap {
  width: 100%;
  max-width: none;
  padding: 0;
}

/* body.work-grid-page(아래)가 페이지 스크롤 자체를 막지만, 트랙패드
   관성/바운스가 그 위로 새는 경우까지 막기 위한 이중 안전장치 */
body.work-grid-page {
  height: 100vh;
  overflow: hidden;
  overscroll-behavior: none;
}

/* ── 전시장 출구(EXIT 문) 경유 진입 시 흰 화면 페이드인 ──────────────────
   work.html의 출구 시퀀스(화면이 따뜻한 흰 빛으로 덮인 뒤 이동)와 이어지도록,
   ?from=exit로 진입한 경우에만(html.from-exit — work-grid.html <head> 인라인
   스크립트가 첫 페인트 전에 부여) 같은 색의 오버레이가 서서히 걷힌다. */
html.from-exit body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: #fff7ea; /* work.html .game-exit-fade와 동일한 따뜻한 화이트 */
  pointer-events: none;
  animation: exit-fade-in 1.2s ease 0.15s forwards;
}

@keyframes exit-fade-in {
  from { opacity: 1; }
  to { opacity: 0; visibility: hidden; }
}

@media (prefers-reduced-motion: reduce) {
  html.from-exit body::after { animation-duration: 0.3s; }
}

.carousel {
  position: relative;
  height: 620px;
  display: flex;
  align-items: center;
  justify-content: center;
  perspective: 1400px;
}

/* work-grid 페이지의 캐러셀은 뷰포트 기반으로 크게 — 중앙 카드가 화면 높이의
   약 74%를 차지한다(카드 비율 300:520은 그대로, --card-h 하나로 폭까지 파생).
   work-grid.js가 카드 실제 폭에서 슬롯 간격(SLOT_PX)을 다시 계산하므로 JS
   수정 없이 이 변수만 조절하면 된다. */
body.work-grid-page .carousel {
  --card-h: clamp(380px, 72vh, 900px);
  height: calc(var(--card-h) + 60px);
  perspective: 1800px;
}

body.work-grid-page .carousel-card {
  width: calc(var(--card-h) * 0.577); /* 300:520 비율 유지 */
  height: var(--card-h);
}

body.work-grid-page .carousel-card-cat { font-size: 13px; }
body.work-grid-page .carousel-card-title { font-size: 17px; }
body.work-grid-page .carousel-card-info { padding: 18px 22px; }

.carousel-track {
  position: relative;
  width: 100%;
  height: 100%;
}

.carousel-card {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 300px;
  height: 520px;
  border-radius: 16px;
  overflow: hidden;
  background: var(--bg-raised);
  border: 1px solid var(--hairline);
  cursor: pointer;
  transition: transform 0.6s cubic-bezier(0.22, 1, 0.36, 1),
              opacity 0.6s ease, box-shadow 0.6s ease, border-color 0.6s ease;
  transform-origin: center center;
}

.carousel-card img {
  width: 100%;
  height: 78%;
  object-fit: cover;
}

/* v5.6: 카드 이미지를 background로 그린다 — 관리자 세로형 프레이밍(crop.portrait)
   을 background-size/position으로 그대로 반영하기 위함(work-grid.js
   applyCardFraming). 크롭이 없으면 cover 중앙 = 예전 <img object-fit:cover>와 동일. */
.carousel-card-media {
  width: 100%;
  height: 78%;
  background-size: cover;
  background-position: 50% 50%;
  background-repeat: no-repeat;
  background-color: var(--bg-raised);
}

/* 안쪽 전시실을 들여다보는 유리창 느낌의 은은한 반사광 (이미지 영역에만) */
.carousel-card::before {
  content: "";
  position: absolute;
  inset: 0 0 22% 0;
  z-index: 2;
  pointer-events: none;
  background: linear-gradient(115deg, rgba(255, 255, 255, 0.08) 0%, transparent 28%, transparent 72%, rgba(255, 255, 255, 0.04) 100%);
}

.carousel-card-info {
  padding: 14px 18px;
}

.carousel-card-cat {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  margin: 0 0 4px;
}

.carousel-card-title {
  font-size: 14px;
  color: var(--ink);
  margin: 0;
  font-weight: 500;
}

.carousel-card[data-cat="motion"] .carousel-card-cat { color: var(--motion); }
.carousel-card[data-cat="ai"] .carousel-card-cat { color: var(--ai); }
.carousel-card[data-cat="apps"] .carousel-card-cat { color: var(--apps); }
.carousel-card[data-cat="special"] .carousel-card-cat { color: var(--violet); }

.carousel-card.is-active[data-cat="motion"] { border-color: var(--motion); box-shadow: 0 0 46px 6px rgba(var(--motion-rgb), 0.4); }
.carousel-card.is-active[data-cat="ai"] { border-color: var(--ai); box-shadow: 0 0 46px 6px rgba(var(--ai-rgb), 0.4); }
.carousel-card.is-active[data-cat="apps"] { border-color: var(--apps); box-shadow: 0 0 46px 6px rgba(var(--apps-rgb), 0.4); }
/* special은 violet(기획전 색). 나머지 전부(media·sculpture·behind·미지정 —
   실데이터에 sculpture/behind도 존재)는 아래 기본 규칙이 아이보리로 받는다.
   예전엔 motion/ai/apps만 매핑돼 그 외 슬롯은 활성 카드인데도 강조가 아예
   안 걸렸다. 기본 규칙은 특정도(0,2,0)라 위 [data-cat] 규칙들(0,3,0)이
   항상 이긴다 — 선언 순서와 무관하게 안전. */
.carousel-card.is-active[data-cat="special"] { border-color: var(--violet); box-shadow: 0 0 46px 6px rgba(var(--violet-rgb), 0.4); }
.carousel-card.is-active { border-color: var(--ink); box-shadow: 0 0 46px 6px rgba(var(--ink-rgb), 0.4); }

.carousel-nav {
  display: flex;
  justify-content: center;
  gap: 10px;
  margin-top: 28px;
}

.carousel-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--hairline-strong);
  border: none;
  cursor: pointer;
  transition: all 0.3s ease;
  padding: 0;
}

.carousel-dot.is-active {
  width: 20px;
  border-radius: 3px;
  background: var(--ink);
}

.carousel-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 50;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1px solid var(--hairline-strong);
  background: rgba(11, 12, 16, 0.55);
  backdrop-filter: blur(6px);
  color: var(--ink);
  font-size: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: border-color 0.2s ease, background 0.2s ease, transform 0.2s ease;
}

@media (hover: hover) {
  .carousel-arrow:hover {
    border-color: var(--ink);
    background: var(--bg-raised);
  }
}

/* base transform(translateY(-50%))이 공통 :active 규칙을 이기므로 눌림
   피드백을 여기서 직접 합성한다 — 공통 규칙과 같은 0.94/0.12s */
.carousel-arrow:active {
  transform: translateY(-50%) scale(0.94);
  transition: border-color 0.2s ease, background 0.2s ease, transform 0.12s ease;
}

.carousel-arrow.prev { left: 8px; }
.carousel-arrow.next { right: 8px; }

@media (max-width: 720px) {
  .carousel-arrow { width: 36px; height: 36px; }
}

/* ── About 페이지 ────────────────────────────────────────── */
.about-grid {
  display: grid;
  grid-template-columns: 320px 1fr;
  gap: 64px;
  padding: 40px 0 100px;
}

.about-portrait {
  position: relative;
  aspect-ratio: 4/5;
  border-radius: 16px;
  background: var(--bg-raised);
  border: 1px solid var(--hairline);
  overflow: hidden;
}

.about-portrait img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* 사진 파일이 없거나 로드에 실패하면(onerror) img가 스스로를 제거하고
   이 클래스를 붙인다 — 이니셜 모노그램을 보여주는 은은한 플레이스홀더 */
.about-portrait.is-placeholder::after {
  content: "허";
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-size: 64px;
  color: var(--ink-muted);
  opacity: 0.45;
}

.about-bio p {
  font-size: 17px;
  color: var(--ink-muted);
  margin: 0 0 20px;
  max-width: 560px;
}

.about-name {
  font-family: var(--font-display);
  font-size: clamp(22px, 2.6vw, 28px);
  font-weight: 600;
  margin: 0 0 20px;
}

.about-name-en {
  font-family: var(--font-body);
  font-size: 0.58em;
  font-weight: 400;
  color: var(--ink-muted);
}

/* 한/영 소개 토글 */
.about-lang-toggle {
  display: inline-flex;
  gap: 4px;
  padding: 4px;
  margin-bottom: 20px;
  border: 1px solid var(--hairline);
  border-radius: 999px;
}

.about-lang-btn {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.04em;
  padding: 7px 16px;
  border-radius: 999px;
  border: none;
  background: none;
  color: var(--ink-muted);
  cursor: pointer;
  transition: color 0.2s ease, background 0.2s ease;
}

@media (hover: hover) {
  .about-lang-btn:hover { color: var(--ink); }
}

.about-lang-btn.is-active {
  color: var(--ink);
  background: rgba(255, 255, 255, 0.08);
}

.about-lang-panel[hidden] { display: none; }

/* Main Tools — JetBrains Mono 라벨 스타일 태그 목록 */
.about-tools {
  margin-top: 36px;
  padding-top: 24px;
  border-top: 1px solid var(--hairline);
}

.about-tools-heading {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin: 0 0 14px;
}

.about-tools-list {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 8px 10px;
  margin: 0;
  padding: 0;
}

.about-tools-list li {
  font-family: var(--font-mono);
  font-size: 12.5px;
  letter-spacing: 0.02em;
  padding: 6px 12px;
  border: 1px solid var(--hairline);
  border-radius: 6px;
  color: var(--ink-muted);
  white-space: nowrap;
}

/* ── Contact 페이지 ──────────────────────────────────────── */
.contact-hero {
  padding: 96px 0 60px;
  text-align: center;
}

.contact-links {
  display: flex;
  justify-content: center;
  gap: 40px;
  padding-bottom: 120px;
  flex-wrap: wrap;
}

.contact-link {
  display: flex;
  flex-direction: column;
  gap: 6px;
  align-items: center;
  padding: 24px 32px;
  border: 1px solid var(--hairline);
  border-radius: 12px;
  transition: border-color 0.2s ease;
  min-width: 180px;
}

@media (hover: hover) {
  .contact-link:hover { border-color: var(--hairline-strong); }
}

.contact-link-label {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--ink-muted);
}

.contact-link-value { font-size: 16px; }

/* ── 전역 오버레이 패널 (About / Contact) ─────────────────── */
body.overlay-open { overflow: hidden; }

.overlay-backdrop {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(4, 4, 6, 0.75);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
}

.overlay-backdrop.is-open {
  opacity: 1;
  pointer-events: auto;
}

.overlay-panel {
  position: fixed;
  inset: 0;
  z-index: 201;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px;
  opacity: 0;
  pointer-events: none;
  transform: translateY(24px);
  transition: opacity 0.4s cubic-bezier(0.22, 1, 0.36, 1),
              transform 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

.overlay-panel.is-open {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0);
}

.overlay-frame {
  position: relative;
  width: min(640px, 100%);
  max-height: 84vh;
  border-radius: 16px;
  background: linear-gradient(160deg, #1d1e25, #101116);
  border: 1px solid var(--hairline-strong);
  box-shadow:
    0 34px 64px -24px rgba(0, 0, 0, 0.75),
    inset 0 0 0 1px rgba(255, 255, 255, 0.03),
    0 0 60px 6px var(--glow-color, rgba(241, 239, 231, 0.16));
  overflow: hidden;
}

.overlay-scroll {
  max-height: 84vh;
  overflow-y: auto;
  padding: 48px 48px 56px;
}

.overlay-close {
  position: absolute;
  top: 18px;
  right: 18px;
  z-index: 2;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1px solid var(--hairline-strong);
  background: rgba(255, 255, 255, 0.03);
  color: var(--ink-muted);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease;
}

@media (hover: hover) {
  .overlay-close:hover {
    color: var(--ink);
    border-color: var(--ink-muted);
    background: rgba(255, 255, 255, 0.08);
  }
}

.overlay-panel-heading {
  font-family: var(--font-display);
  font-size: clamp(24px, 3vw, 32px);
  margin: 0 0 32px;
}

.overlay-panel .about-grid {
  grid-template-columns: 1fr;
  gap: 32px;
  padding: 0;
}

.overlay-panel .about-portrait {
  max-width: 200px;
  margin: 0 auto;
}

.overlay-panel .about-bio p { max-width: none; }

.overlay-contact-list {
  border-top: 1px solid var(--hairline);
}

.overlay-contact-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 24px;
  padding: 18px 0;
  border-bottom: 1px solid var(--hairline);
  transition: color 0.2s ease;
}

@media (hover: hover) {
  .overlay-contact-row:hover { color: var(--ink); }
}

.overlay-contact-label {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.06em;
  color: var(--ink-muted);
  text-transform: uppercase;
}

.overlay-contact-value { font-size: 15px; }

/* ── SNS 아이콘 버튼 — 아이보리 라인 스타일, 호버 시 카테고리 색 글로우 ── */
.social-icon-row {
  display: flex;
  gap: 14px;
  margin-top: 24px;
}

.social-icon-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  flex: 0 0 auto;
  border-radius: 50%;
  border: 1px solid var(--hairline-strong);
  background: rgba(255, 255, 255, 0.02);
  color: var(--ink-muted);
  transition: color 0.2s ease, border-color 0.2s ease, box-shadow 0.25s ease, transform 0.15s ease;
}

.social-icon-btn svg { width: 20px; height: 20px; }

.social-icon-btn:hover {
  color: var(--ink);
  border-color: var(--hairline-strong);
  box-shadow: 0 0 22px 4px var(--glow-color, transparent);
  transform: translateY(-2px);
}

.social-icon-btn:active { transform: translateY(0) scale(0.94); }

.social-icon-btn[data-cat="motion"] { --glow-color: rgba(var(--motion-rgb), 0.55); }
.social-icon-btn[data-cat="ai"] { --glow-color: rgba(var(--ai-rgb), 0.55); }
.social-icon-btn[data-cat="apps"] { --glow-color: rgba(var(--apps-rgb), 0.55); }
.social-icon-btn[data-cat="violet"] { --glow-color: rgba(var(--violet-rgb), 0.55); }

/* ── 작품 디테일 패널 (3D 갤러리 작품 클릭 시) ────────────────────── */
.overlay-frame--wide { width: min(760px, 100%); }

/* ── 작품 상세 — 인스타그램 게시물 스타일(미디어 + 정보/하트/코멘트) ──── */
/* 영상/이미지를 "자세히 보는" 것이 이 패널의 본래 목적이라, 화면 대부분을
   쓰도록 키웠다(was 920px × 84vh). 미디어가 폭의 대부분을 갖고, 정보 열은
   읽기 좋은 최소 폭만 유지한다. */
/* height까지 고정하는 이유: 내용(정보 열) 높이에 맡기면 프레임이 뷰포트의
   60%대에서 멈춰, "화면 대부분을 차지한다"는 목적을 못 채운다. 높이를 못
   박아 미디어 열이 남는 세로 공간을 전부 가져가게 한다. */
.overlay-frame--post {
  width: min(1720px, 96vw);
  height: 92vh;
  max-height: 92vh;
}

.post-layout {
  display: flex;
  height: 100%;
  max-height: 92vh;
}

.post-media {
  position: relative;
  flex: 1 1 70%;
  min-width: 0;
  background: #07080b;
  display: flex;
}

.post-media-content {
  flex: 1;
  min-width: 0;
  display: flex;
}

/* contain — 잘라내지 않고 전체를 보여준다(was cover: 세로 영상/와이드 영상의
   가장자리가 잘려 나갔다). 남는 여백은 어두운 배경이 채운다. */
.post-media img,
.post-media video,
.post-media iframe {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  border: none;
}

/* ── 전체화면 버튼 ─────────────────────────────────────────── */
.post-media-fs-btn,
.post-media-fs-exit {
  position: absolute;
  z-index: 3;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: 1px solid var(--hairline-strong);
  background: rgba(11, 12, 16, 0.62);
  color: var(--ink-muted);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease, opacity 0.2s ease;
}

.post-media-fs-btn { top: 14px; left: 14px; }
.post-media-fs-exit {
  top: 14px;
  right: 14px;
  font-size: 22px;
  line-height: 1;
  display: none; /* 전체화면일 때만 보인다 */
}

@media (hover: hover) {
  .post-media-fs-btn:hover,
  .post-media-fs-exit:hover {
    color: var(--ink);
    border-color: var(--ink-muted);
    background: rgba(11, 12, 16, 0.85);
  }
}

/* 전체화면 중에는 미디어가 화면 전체를 채우고, 나가기 버튼이 나타난다.
   :fullscreen 요소는 기본 배경이 흰색이라 명시적으로 어둡게 둔다. */
.post-media:fullscreen {
  width: 100vw;
  height: 100vh;
  background: #000;
}
.post-media:fullscreen .post-media-fs-btn { display: none; }
.post-media:fullscreen .post-media-fs-exit { display: flex; }

.post-info {
  flex: 1 1 30%;
  min-width: 320px;
  max-width: 460px;
  max-height: 92vh;
  overflow-y: auto;
  border-left: 1px solid var(--hairline);
}

.post-info-scroll { padding: 48px 32px 32px; }

.post-actions {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 20px 0;
  margin: 20px 0;
  border-top: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
}

.post-heart-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  background: none;
  border: none;
  color: var(--ink-muted);
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: 14px;
  padding: 0;
  transition: color 0.2s ease, transform 0.15s ease;
}

@media (hover: hover) {
  .post-heart-btn:hover { color: var(--ink); }
}
.post-heart-btn:active { transform: scale(0.92); }

.post-heart-btn.is-hearted {
  color: #ff5b7a;
}

.post-heart-btn.is-hearted svg {
  fill: #ff5b7a;
  stroke: #ff5b7a;
}

/* ── Behance 링크 (v5.6 신설 → v5.7 전면 재디자인) ────────────────────
   예전에는 하트 옆에 20px 사각 테두리 + 9px "Be" 텍스트라, 실제로는 글자가
   뭉개진 "작은 회색 네모"로만 보였다(스크린샷 확인). 이제:
   · 글리프 자체를 Behance 워드마크(굵은 Bē)로 바꿔 작은 크기에서도 읽힌다
   · 하트(22px)와 같은 위계의 원형 아이콘 버튼(36px) — 다만 "토글"인 하트와
     구분되도록 테두리를 둘러 외부 링크 어피던스를 준다
   · 평상시 아이보리(--ink)로 또렷하게, 호버 시 Behance 브랜드 블루(#1769FF)로
     전환 + 확대 + 글로우. 사이트 팔레트에 블루가 없어 평상시부터 브랜드색을
     쓰면 튀므로, 정체성은 호버(그리고 글리프 형태)가 담당한다.
   · 툴팁 "Behance에서 보기"(i18n 3언어, data-tooltip) — 네이티브 title의
     지연/OS 스타일 대신 사이트 톤에 맞춘 즉시 표시 툴팁.
   Work 인페이지 패널 / Exhibition 상세 패널 / work-detail.html 세 곳 공용. */
.behance-link {
  --behance-blue: #1769ff;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  flex: none;
  border: 1px solid var(--hairline-strong);
  border-radius: 50%;
  color: var(--ink);
  transition: color 0.2s ease, border-color 0.2s ease, transform 0.18s ease, box-shadow 0.25s ease, background 0.2s ease;
}

.behance-link[hidden] { display: none; }

.behance-link-glyph {
  display: block;
  /* 워드마크가 원 안에서 시각적으로 중앙에 오도록 미세 보정 */
  transform: translateY(0.5px);
}

.behance-link:hover,
.behance-link:focus-visible {
  color: var(--behance-blue);
  border-color: rgba(23, 105, 255, 0.75);
  background: rgba(23, 105, 255, 0.12);
  transform: scale(1.12);
  box-shadow: 0 0 18px 2px rgba(23, 105, 255, 0.35);
  outline: none;
}

.behance-link:active { transform: scale(0.96); }

/* 툴팁 — 아이콘 위쪽에 뜬다(패널 하단 잘림 방지). 화살표까지 ::before로. */
.behance-link::after,
.behance-link::before {
  position: absolute;
  bottom: calc(100% + 10px);
  left: 50%;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s ease, transform 0.18s ease;
  transform: translate(-50%, 4px);
}

.behance-link::after {
  content: attr(data-tooltip);
  padding: 6px 10px;
  border-radius: 8px;
  background: rgba(11, 12, 16, 0.95);
  border: 1px solid var(--hairline-strong);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.02em;
  line-height: 1.2;
  white-space: nowrap;
  z-index: 5;
}

.behance-link::before {
  content: "";
  bottom: calc(100% + 5px);
  width: 8px;
  height: 8px;
  background: rgba(11, 12, 16, 0.95);
  border-right: 1px solid var(--hairline-strong);
  border-bottom: 1px solid var(--hairline-strong);
  transform: translate(-50%, 4px) rotate(45deg);
  z-index: 6;
}

.behance-link:hover::after,
.behance-link:focus-visible::after { opacity: 1; transform: translate(-50%, 0); }
.behance-link:hover::before,
.behance-link:focus-visible::before { opacity: 1; transform: translate(-50%, 0) rotate(45deg); }

@media (prefers-reduced-motion: reduce) {
  .behance-link,
  .behance-link::after,
  .behance-link::before { transition: opacity 0.18s ease; }
  .behance-link:hover,
  .behance-link:focus-visible { transform: none; }
}

/* work-detail.html — 본문 흐름 안에 단독으로 놓이므로 위쪽 여백만 준다 */
.detail-info .behance-link { margin-top: 28px; }

/* Work 인페이지 상세 패널의 "전체 페이지로 보기" — work-detail.html로 가는 보조 링크 */
.post-detail-page-link {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--ink-muted);
  border-bottom: 1px solid var(--hairline-strong);
  transition: color 0.2s ease;
}
@media (hover: hover) {
  .post-detail-page-link:hover { color: var(--ink); }
}

.post-view-count {
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--ink-muted);
  margin-left: auto;
}

/* 하트 RPC 실패 시 잠깐 떴다 사라지는 토스트 — 화면은 원상태로 유지한 채
   "잠시 후 다시 시도해주세요"만 짧게 안내한다(하트가 실제로 저장되지 않았는데
   눌린 것처럼 보이는 혼란을 없애기 위함). */
.post-heart-toast {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.02em;
  color: #e8a33d;
}

.post-comments-label {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin: 0 0 14px;
}

.post-comment-list {
  list-style: none;
  margin: 0 0 20px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-height: 260px;
  overflow-y: auto;
}

.post-comment-item { font-size: 14px; line-height: 1.6; }

.post-comment-nick {
  font-weight: 600;
  margin-right: 8px;
}

.post-comment-time {
  display: block;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--ink-muted);
  margin-top: 2px;
}

.post-comment-empty {
  font-size: 13px;
  color: var(--ink-muted);
}

.post-comment-form {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.post-comment-nickname,
.post-comment-input {
  font-family: var(--font-body);
  font-size: 14px;
  background: var(--bg-raised);
  border: 1px solid var(--hairline);
  border-radius: 8px;
  color: var(--ink);
  padding: 10px 12px;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

/* 폼 입력 포커스 — 브라우저 기본 아웃라인 대신 사이트 문법(테두리
   hairline-strong + 은은한 글로우). 앰버(--motion-rgb)는 3D 갤러리의 행동
   요소(근접 프롬프트 E 배지 글로우)와 같은 색 계열이라 방명록/코멘트
   "작성 행위"의 색으로 이어진다. 텍스트 입력은 마우스 포커스도
   :focus-visible에 매칭되므로 키보드/클릭 모두 같은 스타일을 받는다. */
.post-comment-nickname:focus-visible,
.post-comment-input:focus-visible,
.guestbook-message:focus-visible {
  outline: none;
  border-color: var(--hairline-strong);
  box-shadow: 0 0 14px 1px rgba(var(--motion-rgb), 0.18);
}

.post-comment-nickname { width: 140px; }

.post-comment-input-row {
  display: flex;
  gap: 8px;
}

.post-comment-input { flex: 1; min-width: 0; }

.post-comment-submit {
  font-family: var(--font-mono);
  font-size: 13px;
  padding: 0 18px;
  border-radius: 8px;
  border: 1px solid var(--hairline-strong);
  background: var(--ink);
  color: var(--bg);
  cursor: pointer;
  transition: opacity 0.2s ease;
}

@media (hover: hover) {
  .post-comment-submit:hover { opacity: 0.85; }
}

.post-comment-status {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--ink-muted);
  min-height: 1em;
  margin: 0;
}

/* 세로로 쌓이기 전 중간 폭 — 정보 열의 최소 폭(320px)을 지키면서 미디어가
   남는 공간을 전부 갖도록 비율만 완화한다. */
@media (max-width: 1100px) {
  .post-info { min-width: 280px; max-width: 380px; }
}

@media (max-width: 760px) {
  .overlay-frame--post { width: 100%; height: 100vh; max-height: 100vh; }
  .post-layout { flex-direction: column; height: 100%; max-height: none; }
  /* 모바일에서는 미디어가 화면 위쪽 절반 정도를 차지하고 정보가 그 아래로
     스크롤된다. aspect-ratio 고정(4/3)은 세로 영상을 크게 레터박스 처리했으므로
     높이 기반으로 바꾼다. */
  .post-media { aspect-ratio: auto; height: 46vh; flex: none; }
  .post-info {
    border-left: none;
    border-top: 1px solid var(--hairline);
    max-height: none;
    min-width: 0;
    max-width: none;
  }
  .post-media-fs-btn,
  .post-media-fs-exit { width: 34px; height: 34px; }
}

/* ── 방명록 패널 (마무리 존 스탠드에서 열림) ────────────────────────── */
.guestbook-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-bottom: 24px;
  border-bottom: 1px solid var(--hairline);
}

.guestbook-form .post-comment-nickname { width: 160px; }

.guestbook-message {
  font-family: var(--font-body);
  font-size: 14px;
  background: var(--bg-raised);
  border: 1px solid var(--hairline);
  border-radius: 8px;
  color: var(--ink);
  padding: 10px 12px;
  resize: vertical;
  min-height: 56px;
  transition: border-color 0.2s ease, box-shadow 0.2s ease; /* focus 글로우용 — .post-comment-input과 동일 */
}

.guestbook-form-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.guestbook-list {
  max-height: 360px;
  margin-top: 14px;
}

.detail-panel-meta {
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--ink-muted);
  margin: 4px 0 24px;
}

.detail-panel-media {
  border-radius: 12px;
  overflow: hidden;
  background: var(--bg-raised);
  border: 1px solid var(--hairline);
  margin-bottom: 24px;
  aspect-ratio: 16 / 9;
}

.detail-panel-media img,
.detail-panel-media iframe {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border: none;
}

.detail-panel-desc {
  font-size: 16px;
  line-height: 1.75;
  color: var(--ink-muted);
  max-width: 60ch;
  margin: 0;
}

.finale-video-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  text-align: center;
}

.finale-video-placeholder p {
  font-family: var(--font-mono);
  letter-spacing: 0.1em;
  color: var(--ink-muted);
  margin: 0;
}

.finale-video-placeholder-sub { font-size: 12px; opacity: 0.7; }

@media (max-width: 640px) {
  .overlay-panel { padding: 0; align-items: flex-end; }
  .overlay-frame { width: 100%; max-height: 92vh; border-radius: 16px 16px 0 0; }
  .overlay-scroll { max-height: 92vh; padding: 56px 20px 32px; }
  /* 상세 패널만은 바텀시트가 아니라 전체 높이를 쓴다 — 영상을 크게 보는 게
     목적이라 위쪽 여백이 아깝다. */
  .overlay-frame--post { max-height: 100vh; border-radius: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .overlay-panel,
  .overlay-backdrop { transition: none; }
}

/* ── 푸터 ────────────────────────────────────────────────── */
.footer {
  border-top: 1px solid var(--hairline);
  padding: 32px 0;
}

.footer .wrap {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.footer-text {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--ink-muted);
}

/* ── 반응형 ──────────────────────────────────────────────── */
@media (max-width: 860px) {
  .about-grid { grid-template-columns: 1fr; }
  .nav-links { gap: 20px; }
  .carousel { height: 460px; }
  .carousel-card { width: 220px; height: 380px; }
}

/* 좁은 화면에서 로고 + 5개 메뉴가 한 줄에 다 안 들어가 "Contact"가
   잘리던 문제 — 로고와 메뉴를 두 줄로 감싸고 메뉴 자체도 필요하면
   줄바꿈되도록 하여 어떤 항목도 화면 밖으로 잘리지 않게 한다. */
@media (max-width: 640px) {
  .nav .wrap {
    flex-wrap: wrap;
    justify-content: center;
    height: auto;
    padding-top: 14px;
    padding-bottom: 14px;
    row-gap: 12px;
  }
  .nav-logo { flex: 0 0 100%; justify-content: center; }
  .nav-links {
    flex-wrap: wrap;
    justify-content: center;
    gap: 10px 18px;
  }
  .nav-links a,
  .nav-links button.nav-link-btn { font-size: 13px; }
  .nav-links a.active::after { bottom: -8px; }
}


@media (prefers-reduced-motion: reduce) {
  * { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}

/* ============================================================
   커스텀 커서 (Home 전용 — index.html) — 작은 도트 + 지연되며 따라오는 링.
   Exhibition(work.html)은 이미 자체 조준점(크로스헤어) 시스템이 있어 여기
   적용하지 않는다(home-cursor.js가 index.html에서만 로드됨). 터치 기기는
   home-cursor.js가 아예 초기화하지 않고, 아래 pointer:coarse 쿼리로도
   한 번 더 숨겨 이중으로 안전하게 막는다.
   ============================================================ */
.cursor-dot,
.cursor-ring {
  position: fixed;
  top: 0;
  left: 0;
  border-radius: 50%;
  pointer-events: none;
  z-index: 9999;
  transform: translate3d(-50%, -50%, 0);
  opacity: 0;
  transition: opacity 0.2s ease;
}
body.has-custom-cursor .cursor-dot,
body.has-custom-cursor .cursor-ring {
  opacity: 1;
}
.cursor-dot {
  width: 6px;
  height: 6px;
  background: var(--ink);
  box-shadow: 0 0 6px rgba(241, 239, 231, 0.5);
}
.cursor-ring {
  width: 34px;
  height: 34px;
  border: 1.5px solid rgba(241, 239, 231, 0.45);
  background: transparent;
  transition: width 0.25s ease, height 0.25s ease, border-color 0.25s ease, background 0.25s ease, opacity 0.2s ease;
}
.cursor-ring.is-hover {
  width: 58px;
  height: 58px;
  border-color: var(--cursor-cat-color, var(--motion));
  background: color-mix(in srgb, var(--cursor-cat-color, var(--motion)) 14%, transparent);
}
.cursor-ring.is-click {
  transition: width 0.12s ease, height 0.12s ease;
  width: 22px;
  height: 22px;
}
/* cursor:none은 has-custom-cursor가 붙은(=비터치, JS 초기화 완료) 경우에만 —
   초기화 전이나 터치 기기에서는 항상 기본 커서를 그대로 둔다. */
body.has-custom-cursor,
body.has-custom-cursor a,
body.has-custom-cursor button,
body.has-custom-cursor .ticket-card {
  cursor: none; /* .ticket-card는 div인데 자체 cursor:pointer(ticket.css)가 있어 명시 필요 */
}
@media (pointer: coarse) {
  .cursor-dot,
  .cursor-ring {
    display: none !important;
  }
}
