/* 장면은 가장자리에서 선명하고 본문 뒤에서는 잦아들어 읽기 축을 지킵니다. */
.cosmos-stage { position: fixed; inset: 0; z-index: 0; width: 100%; height: 100%; pointer-events: none; contain: strict; opacity: .82; mask-image: linear-gradient(90deg,#000, rgb(0 0 0 / .18) 30%, rgb(0 0 0 / .18) 70%,#000); }
.chapter { background: linear-gradient(110deg,color-mix(in oklab,var(--sc) 2%,transparent),transparent 46%); border-top-color: color-mix(in oklab,var(--sc) 16%,transparent); }
.chapter::before { display: block; position: absolute; inset: 0 auto auto 50%; width: min(900px,100%); height: 160px; translate: -50% 0; background: radial-gradient(ellipse at 50% 0,color-mix(in oklab,var(--sc) 7%,transparent),transparent 70%); pointer-events: none; }
.chapter::after { display: block; content: ''; position: absolute; top: -3px; left: 50%; width: 5px; height: 5px; rotate: 45deg; background: var(--sc); box-shadow: 0 0 14px color-mix(in oklab,var(--sc) 18%,transparent); }
.chapter-opening { position: relative; }
.chapter-kicker { letter-spacing: .06em; }
.chapter-kicker .chapter-index { color: var(--sc); }
.chapter-meaning { border-bottom: 1px solid color-mix(in oklab,var(--sc) 45%,transparent); padding-bottom: 3px; }
.chapter-statement { font-weight: 450; letter-spacing: -.05em; }
.chapter-role { letter-spacing: .1em; }
.chapter-emblem { position: relative; isolation: isolate; }
.chapter-emblem::before, .chapter-emblem::after { content: ''; position: absolute; top: -20px; width: 190px; height: 190px; border: 1px solid color-mix(in oklab,var(--sc) 22%,transparent); border-radius: 50%; pointer-events: none; z-index: -1; }
.chapter-emblem::before { transform: rotate(-28deg) scaleY(.52); }
.chapter-emblem::after { transform: rotate(53deg) scaleY(.72); border-style: dotted; opacity: .7; }
.chapter .chapter-emblem .orb { background: radial-gradient(circle at 50% 55%,color-mix(in oklab,var(--sc) 12%,transparent),transparent 70%); border-color: color-mix(in oklab,var(--sc) 55%,transparent); }
.emblem-caption { color: color-mix(in oklab,var(--sc) 55%,var(--text-2)); letter-spacing: .18em; }
.chapter-epigraph { position: relative; border-color: color-mix(in oklab,var(--sc) 20%,transparent); }
.chapter-epigraph::before { content: ''; position: absolute; top: -1px; left: 0; width: 42px; height: 1px; background: var(--sc); }
.chapter-epigraph .b-ref { letter-spacing: .08em; }
.section-label { color: var(--sc) !important; }
.tb-num { border-color: var(--sc); color: var(--sc); }
.topbar { background: linear-gradient(90deg,rgb(8 8 13 / .96),rgb(15 12 22 / .96),rgb(8 8 13 / .96)); }
.minimap { opacity: .88; }
.audio-controls { border-bottom-color: rgb(180 160 208 / .3); background: rgb(8 8 13 / .88); }
.project-filters { gap: 28px; }
.project-filters button { display: inline-flex; align-items: center; gap: 8px; }
.project-filters button::before { content: ''; width: 4px; height: 4px; border-radius: 50%; border: 1px solid var(--text-2); }
.project-filters button[aria-pressed='true']::before { background: var(--sc); border-color: var(--sc); box-shadow: 0 0 8px color-mix(in oklab,var(--sc) 35%,transparent); }
.project-pagination { position: relative; }
.project-pagination button { min-width: 32px; }
.project-pagination button[aria-current] { border-color: var(--sc); }
.project-entry { position: relative; }
.unified-projects .project-entry > summary { transition: background .35s; }
.unified-projects .project-entry > summary:hover { background: linear-gradient(90deg,color-mix(in oklab,var(--sc) 4%,transparent),transparent); }
.project-cover { padding: 7px 0; border-bottom: 1px solid color-mix(in oklab,var(--sc) 30%,transparent); }
.project-year { letter-spacing: .08em; color: color-mix(in oklab,var(--sc) 65%,var(--text-2)); }
.project-heading b { transition: color .25s; }
.project-entry > summary:hover .project-heading b { color: var(--sc); }
.project-gallery figure > a { border-bottom: 1px solid color-mix(in oklab,var(--sc) 30%,transparent); padding-bottom: 10px; }
.artwork-frame { position: relative; padding-bottom: 12px; }
.artwork-frame::before { content: ''; position: absolute; left: 0; bottom: 0; width: 36px; border-bottom: 1px solid var(--sc); }
.artwork-card figcaption { border-top-color: color-mix(in oklab,var(--sc) 25%,transparent); }
.arka-nav.is-reader-nav { border-color: color-mix(in oklab,var(--sc) 28%,transparent); }
.arka-nav a[aria-current] { color: var(--sc); }
.arka-index { color: var(--sc); }
.contact-address { border-color: color-mix(in oklab,var(--sc) 25%,transparent); }
.contact-links a:hover { color: var(--sc); }
@media (prefers-reduced-motion: no-preference) {
.chapter.is-in-view .chapter-emblem::before { animation: seal-orbit 65s linear infinite; }
.chapter.is-in-view .chapter-emblem::after { animation: seal-orbit-back 85s linear infinite; }
}
@keyframes seal-orbit { from { transform: rotate(-28deg) scaleY(.52); } to { transform: rotate(332deg) scaleY(.52); } }
@keyframes seal-orbit-back { from { transform: rotate(53deg) scaleY(.72); } to { transform: rotate(-307deg) scaleY(.72); } }
@media(max-width:767px) {
.cosmos-stage { opacity: .65; mask-image: linear-gradient(90deg,#000,rgb(0 0 0 / .12) 24%,rgb(0 0 0 / .12) 76%,#000); }
.chapter-emblem::before, .chapter-emblem::after { width: 110px; height: 110px; top: -14px; }
.project-filters { gap: 20px; }
.project-filters button { gap: 5px; }
.chapter-statement { font-weight: 500; }
}

/* 지도는 별도로 회전시키고 노드의 등장 효과가 복귀마다 재시작되지 않게 합니다. */
.ht-tree { transform-origin: 50% 50%; will-change: transform; z-index: 2; }
/* 나무를 화면에 고정한 채 눕히는 동안 다음 섹션이 올라와 겹치지 않도록 그만큼 빈 공간을 둡니다 (sephirot.js PIN_RATIO와 같은 값) */
.js #tree { margin-bottom: 44svh; }
@media (prefers-reduced-motion: reduce) { .js #tree { margin-bottom: 0; } }
.tree-grown .ht-tree .node, .tree-grown .ht-tree .tree-svg, .tree-grown .ht-tree .ain { animation: none; }
.tree-grown .ht-tree .path-signal { animation: none; opacity: 0; stroke-width: 1.5; stroke-dasharray: .12 .88; }
@media (prefers-reduced-motion: no-preference) {
.hero-tree.is-tracing .ht-tree .path-signal { animation: constellation-flow 1.15s cubic-bezier(.25,.1,.25,1) calc(var(--d,0) * .65ms) both; }
}
@keyframes constellation-flow {
0% { stroke-dashoffset: 1.12; opacity: 0; }
16% { opacity: .85; }
75% { opacity: .5; }
100% { stroke-dashoffset: -.12; opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .ht-tree { transform: none !important; } }
/* 고정된 나무가 히어로 경계 밖으로 내려가도 잘리지 않고 다음 섹션 위에 그려지도록 합니다 (가로 넘침은 body가 막습니다) */
.js .hero-tree { overflow: visible; position: relative; z-index: 3; }
/* 나무 회전 다이얼: 히어로 좌상단 기준으로 JS가 위치를 잡습니다. 글자·선은 Kether 보라를 옅게 씁니다 */
.ht-dial { position: absolute; left: 0; top: 0; z-index: 1; pointer-events: none; opacity: 0; overflow: visible; will-change: transform, opacity; }
.ht-dial .dial-line { fill: none; stroke: color-mix(in oklab, var(--text-2, #a1a1aa) 55%, transparent); stroke-width: .5; vector-effect: non-scaling-stroke; }
.ht-dial .dial-dash { stroke-dasharray: 2 4; }
.ht-dial .dial-arm { stroke: color-mix(in oklab, #a78bfa 70%, transparent); }
.ht-dial .dial-text { fill: var(--text-2, #a1a1aa); font: 500 5px/1 "Geist Mono", ui-monospace, monospace; text-anchor: middle; letter-spacing: .08em; }
.ht-dial .dial-readout { font-size: 5.5px; fill: var(--text-1, #fafafa); }
@media (prefers-reduced-motion: reduce) { .ht-dial { display: none; } }
/* 도착 점등: 세피라마다 80ms씩 늦게 원이 채워졌다 빠지고, 파문 고리 두 겹이 퍼지며, 글자가 살짝 튀어 오릅니다 */
.ht-tree .node-ripple { fill: none; stroke: var(--sc, currentColor); stroke-width: 1.5; opacity: 0; pointer-events: none; transform-box: fill-box; transform-origin: center; }
.ht-tree .node.is-lit .node-ripple { animation: node-ripple 1.1s cubic-bezier(.16,1,.3,1) both; }
.ht-tree .node.is-lit .node-ripple.r1 { animation-delay: 160ms; }
.ht-tree .node.is-lit .node-ring { animation: node-flash .9s cubic-bezier(.34,1.56,.64,1) both; }
.ht-tree .node.is-lit .node-name, .ht-tree .node.is-lit .node-sym { animation: node-pop .7s cubic-bezier(.34,1.56,.64,1) 60ms both; }
@keyframes node-ripple { 0% { opacity: .9; transform: scale(1); } 100% { opacity: 0; transform: scale(1.9); stroke-width: .3; } }
@keyframes node-flash { 0% { fill: transparent; stroke-width: 1.5; } 35% { fill: color-mix(in oklab, var(--sc, #fff) 38%, transparent); stroke-width: 3.5; } 100% { stroke-width: 1.5; } }
@keyframes node-pop { 0% { opacity: .2; } 40% { opacity: 1; } 100% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .ht-tree .node-ripple { display: none; } }
/* 케테르로 다이브하는 동안 케테르를 뺀 나머지 세피라·경로는 --others 값에 맞춰 사라집니다 */
.hero-tree.is-diving .ht-tree .node, .hero-tree.is-diving .ht-tree .path-badge > *, .hero-tree.is-diving .ht-tree .path, .hero-tree.is-diving .ht-tree svg line, .hero-tree.is-diving .ht-tree svg path:not([data-seph="1"] path), .hero-tree.is-diving .ht-tree .veil { opacity: var(--others, 1) !important; }
/* 케테르 원은 날아가는 원이 대신하므로 즉시 숨깁니다 */
.hero-tree.is-diving .ht-tree .node[data-seph="1"] { opacity: 0 !important; }
/* 케테르 장으로 넘어가는 빛 막: 아래에서 위로 옅은 보라가 차오릅니다 */
.k-wash { position: fixed; inset: 0; z-index: 1; pointer-events: none; opacity: 0; background: linear-gradient(to top, color-mix(in oklab, var(--c1) 22%, transparent) 0%, color-mix(in oklab, var(--c1) 8%, transparent) 45%, transparent 80%); will-change: transform, opacity; }
@media (prefers-reduced-motion: reduce) { .k-wash { display: none; } }
.ht-tree svg { overflow: visible; } /* 가로 배치로 옮겨 간 세피라가 viewBox 밖으로 나가도 보이게 */
/* 첫 화면의 세로 나무는 흰 실루엣으로만 보이고 누를 수 없습니다.
   가로로 바뀌며 세피라가 하나씩 도착(is-lit)하는 순간 자기 색을 되찾고 클릭할 수 있게 됩니다 */
.js .ht-tree .node { transition: filter .6s var(--ease-smooth, ease-out), opacity .6s var(--ease-smooth, ease-out); }
.js .ht-tree .node:not(.is-lit) { filter: grayscale(1) brightness(1.6); opacity: .7; pointer-events: none; }
.js .ht-tree .path-badge { transition: opacity .6s ease-out; }
.js .hero-tree:not(.is-laid) .ht-tree .path-badge { opacity: .45; }
@media (prefers-reduced-motion: reduce) { .js .ht-tree .node:not(.is-lit) { filter: none; opacity: 1; pointer-events: auto; } }
/* 말쿠트의 라벤더는 채도가 낮아 실루엣(흰색)과 구분되지 않으므로, 나무 안에서만 조금 더 진한 라벤더를 씁니다 */
.ht-tree .node[data-seph='10'] { --sc: oklch(0.74 0.15 295); }
/* 가로 배치 뒤 배경: --laid(0~1)에 맞춰 떠오르고, 궤도는 서로 다른 속도와 방향으로 천천히 돕니다 */
.ht-backdrop { opacity: calc(var(--laid, 0) * .9); pointer-events: none; }
.ht-backdrop .b-orbit { fill: none; stroke: rgb(255 255 255 / .07); stroke-width: 1; vector-effect: non-scaling-stroke; }
.ht-backdrop .b-o2 { stroke-dasharray: 2 10; stroke: rgb(255 255 255 / .1); }
.ht-backdrop .b-o3 { stroke-dasharray: 1 18; }
.ht-backdrop .b-ticks line { stroke: rgb(255 255 255 / .12); vector-effect: non-scaling-stroke; }
.ht-backdrop .b-horizon { stroke: rgb(255 255 255 / .06); stroke-dasharray: 3 7; vector-effect: non-scaling-stroke; }
.ht-backdrop .b-sat { fill: var(--c1); }
.ht-backdrop .b-s1 { fill: var(--c6); } .ht-backdrop .b-s2 { fill: var(--c9); }
.ht-backdrop .b-ticks, .ht-backdrop .b-o2, .ht-backdrop .b-sat { transform-box: view-box; transform-origin: 200px 320px; }
.ht-backdrop .b-ticks { animation: b-spin 120s linear infinite; }
.ht-backdrop .b-o2 { animation: b-spin 90s linear infinite reverse; }
.ht-backdrop .b-s0 { animation: b-spin 26s linear infinite; }
.ht-backdrop .b-s1 { animation: b-spin 40s linear infinite reverse; }
.ht-backdrop .b-s2 { animation: b-spin 60s linear infinite; }
@keyframes b-spin { to { rotate: 360deg; } }
@keyframes b-orbit { from { offset-distance: 0%; } to { offset-distance: 100%; } }
@media (prefers-reduced-motion: reduce) { .ht-backdrop * { animation: none !important; } }
/* 이미지 반사: 모든 이미지 아래에 옅게 비치는 반사를 둡니다.
   갤러리·아트워크는 기존 .image-mirror 요소를, 그 밖의 이미지(캐릭터 원, 프로젝트 표지 등)는 box-reflect를 씁니다.
   반사는 물 위처럼 아주 천천히 일렁여 정적인 느낌을 덜어 줍니다 (Firefox는 box-reflect 미지원이라 반사 없이 보입니다) */
.image-mirror { opacity: .26; transform-origin: top center; animation: mirror-ripple 7s ease-in-out infinite alternate; }
.project-cover img, .orb-art img, .chapter-emblem img, .artwork-card img:not(.image-mirror img) {
-webkit-box-reflect: below 6px linear-gradient(to bottom, transparent 62%, rgb(0 0 0 / .2));
}
@keyframes mirror-ripple { 0% { transform: scaleY(1) skewX(0deg); opacity: .26; } 50% { transform: scaleY(.94) skewX(.6deg); opacity: .2; } 100% { transform: scaleY(1.03) skewX(-.4deg); opacity: .28; } }
@media (prefers-reduced-motion: reduce) { .image-mirror { animation: none; } }
/* 모바일: 소리 버튼이 상단 본문 글자를 가리지 않도록 화면 왼쪽 아래로 옮깁니다 */
@media (max-width: 699px) {
.audio-controls { top: auto !important; height: auto; bottom: calc(12px + env(safe-area-inset-bottom)); left: 12px; right: auto !important; border: 1px solid rgb(180 160 208 / .3); border-radius: 999px; padding: 0 2px; }
.audio-controls .music-control, .audio-controls .sound-control { min-height: 40px; }
}
/* ── 갤러리 관리 창 ───────────────────────────────── */
.artwork-upload { background: transparent; font: inherit; font-size: 13px; cursor: pointer; }
.ga-dialog { width: min(720px, calc(100vw - 32px)); max-height: min(86svh, 820px); padding: 0; border: 1px solid rgb(255 255 255 / .1); border-radius: 20px; background: #121216; color: var(--text, #fafafa); overflow: auto; }
.ga-dialog::backdrop { background: rgb(5 4 8 / .72); }
.ga-dialog[data-busy] { cursor: progress; }
.ga-head { position: sticky; top: 0; z-index: 1; display: flex; align-items: center; justify-content: space-between; padding: 20px 24px; background: #121216; border-bottom: 1px solid rgb(255 255 255 / .06); }
.ga-head h3 { margin: 0; font-size: 18px; font-weight: 600; letter-spacing: -.01em; }
.ga-close { width: 44px; height: 44px; border: 0; border-radius: 10px; background: transparent; color: var(--text-2, #a1a1aa); font-size: 24px; cursor: pointer; }
.ga-close:hover { background: rgb(255 255 255 / .06); color: var(--text, #fafafa); }
.ga-token, .ga-manager { display: grid; gap: 12px; padding: 24px; }
.ga-token label:first-child { font-weight: 600; }
.ga-help { margin: 0; color: var(--text-2, #a1a1aa); font-size: 13px; line-height: 1.7; word-break: keep-all; }
.ga-input { min-height: 44px; padding: 10px 12px; border: 1px solid rgb(255 255 255 / .1); border-radius: 10px; background: #0b0b0e; color: var(--text, #fafafa); font: 14px var(--font-mono, ui-monospace, monospace); }
.ga-input:focus-visible { outline: 2px solid var(--c6, #e8889a); outline-offset: 2px; }
.ga-check { display: inline-flex; align-items: center; gap: 8px; color: var(--text-2, #a1a1aa); font-size: 13px; }
.ga-btn { min-height: 44px; padding: 0 16px; border: 1px solid rgb(255 255 255 / .12); border-radius: 10px; background: transparent; color: var(--text, #fafafa); font: 500 13px inherit; cursor: pointer; transition: background .2s, border-color .2s, transform .15s; white-space: nowrap; }
.ga-btn:hover:not(:disabled) { background: rgb(255 255 255 / .06); border-color: rgb(255 255 255 / .2); }
.ga-btn:active:not(:disabled) { transform: scale(.97); }
.ga-btn:disabled { opacity: .5; cursor: not-allowed; }
.ga-primary { border-color: var(--c6, #e8889a); background: color-mix(in oklab, var(--c6, #e8889a) 18%, transparent); }
.ga-ghost { min-height: 36px; font-size: 12px; color: var(--text-2, #a1a1aa); }
.ga-danger { color: #ff8a8a; border-color: rgb(255 120 120 / .3); }
.ga-danger[data-confirm='1'] { background: rgb(255 90 90 / .16); border-color: #ff6b6b; }
.ga-drop { display: grid; gap: 6px; place-items: center; min-height: 140px; padding: 20px; border: 1px dashed rgb(255 255 255 / .18); border-radius: 14px; text-align: center; cursor: pointer; transition: border-color .2s, background .2s; }
.ga-drop span { color: var(--text-3, #71717a); font-size: 12px; }
.ga-drop:hover, .ga-drop.is-over { border-color: var(--c6, #e8889a); background: color-mix(in oklab, var(--c6, #e8889a) 6%, transparent); }
.ga-file { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.ga-list-head { display: flex; align-items: center; justify-content: space-between; margin-top: 8px; color: var(--text-2, #a1a1aa); font: 12px var(--font-mono, ui-monospace, monospace); letter-spacing: .04em; }
.ga-list { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; }
.ga-item { display: grid; grid-template-columns: 56px 1fr auto auto; gap: 10px; align-items: center; padding: 8px; border: 1px solid rgb(255 255 255 / .06); border-radius: 12px; }
.ga-thumb { width: 56px; height: 56px; border-radius: 8px; object-fit: cover; background: #0b0b0e; }
.ga-thumb.is-missing { opacity: .25; }
.ga-meta { display: flex; align-items: center; gap: 6px; min-width: 0; }
.ga-name { flex: 1; min-width: 0; }
.ga-ext { color: var(--text-3, #71717a); font: 12px var(--font-mono, ui-monospace, monospace); }
.ga-empty { padding: 24px; color: var(--text-3, #71717a); text-align: center; }
.ga-status { min-height: 1.6em; margin: 0; padding: 0 24px 20px; color: var(--text-2, #a1a1aa); font-size: 13px; }
.ga-status[data-tone='error'] { color: #ff8a8a; }
.ga-status[data-tone='ok'] { color: #9be6b4; }
@media (max-width: 560px) { .ga-item { grid-template-columns: 48px 1fr; } .ga-item .ga-btn { grid-column: span 1; } .ga-thumb { width: 48px; height: 48px; } }

/* ── 활성화된 나무 주변 문구: 크게, 넉넉한 간격, 한글 위주 ── */
.ht-captions { opacity: calc(var(--laid, 0)); pointer-events: none; }
.ht-captions text { text-anchor: middle; }
.ht-captions .cap-title { font: 600 24px var(--font-mono, ui-monospace, monospace); letter-spacing: .42em; fill: var(--text, #fafafa); }
.ht-captions .cap-ko { font-family: var(--font-sans, Pretendard, sans-serif); fill: #d4d4d8; }
.ht-captions .cap-lead { font-size: 15px; letter-spacing: .02em; }
.ht-captions .cap-name { font-size: 16px; font-weight: 600; letter-spacing: .02em; fill: var(--text, #fafafa); }
.ht-captions .cap-group { font: 500 10px var(--font-mono, ui-monospace, monospace); letter-spacing: .22em; fill: #9ca3af; }
.ht-captions .cap-bracket { fill: none; stroke: rgb(255 255 255 / .22); vector-effect: non-scaling-stroke; }
@media (max-width: 699px) { .ht-captions { display: none; } }
.hero-tree .ht-coordinate { transition: opacity .5s ease-out; } .hero-tree.is-laid .ht-coordinate { opacity: 0; } /* 가로 나무와 겹치지 않게 활성화되면 숨김 */
/* 스크롤 힌트: 화면 아래 가운데, 글자 아래로 짧은 선이 흘러내립니다 */
.tree-hint { position: fixed; left: 50%; bottom: calc(14px + env(safe-area-inset-bottom)); z-index: 30; display: flex; align-items: center; gap: 12px; padding: 8px 16px; border-radius: 999px; background: rgb(8 8 13 / .72); border: 1px solid rgb(255 255 255 / .1); translate: -50% 8px; opacity: 0; pointer-events: none; transition: opacity .5s ease-out, translate .5s cubic-bezier(.16,1,.3,1); }
.tree-hint.is-shown { opacity: 1; translate: -50% 0; } /* 하단 중앙, 반투명 알약 배경으로 나무 위에서도 읽히게 */
.tree-hint span { font: 600 14px var(--font-sans, Pretendard, sans-serif); letter-spacing: .04em; color: #fafafa; }
.tree-hint-line { position: relative; width: 1px; height: 18px; overflow: hidden; background: rgb(255 255 255 / .14); }
.tree-hint-line::after { content: ''; position: absolute; left: 0; top: -40%; width: 1px; height: 40%; background: #fafafa; animation: hint-drop 1.8s cubic-bezier(.65,0,.35,1) infinite; }
@keyframes hint-drop { to { top: 100%; } }
@media (max-width: 699px) { .tree-hint { left: 50%; translate: -50% 8px; bottom: calc(68px + env(safe-area-inset-bottom)); } .tree-hint.is-shown { translate: -50% 0; } }
@media (prefers-reduced-motion: reduce) { .tree-hint-line::after { animation: none; top: 30%; } }
/* 고대 문자 흐름: 아주 옅게, 줄마다 반대 방향과 다른 속도로 흐릅니다 */
.ht-captions .cap-runes text { text-anchor: start; font: 22px/1 "Noto Sans Symbols 2", "Segoe UI Symbol", serif; letter-spacing: .5em; fill: rgb(220 210 240 / .055); }
.ht-captions .cap-runes { animation: rune-flow 80s linear infinite; }
.ht-captions .cap-r1 { animation-direction: reverse; }
@keyframes rune-flow { from { transform: translateX(0); } to { transform: translateX(-900px); } }
@media (prefers-reduced-motion: reduce) { .ht-captions .cap-runes { animation: none; } }
/* 처음 세로 나무에서는 어떤 원이 어떤 세피라인지 알 수 없게 이름·문양·번호와 경로 글자를 숨기고 빈 원만 보입니다.
   켜지는(is-lit) 순간 하나씩 드러납니다 */
.js .ht-tree .node text, .js .ht-tree .node .node-num-bg { transition: opacity .5s ease-out; }
.js .ht-tree .node:not(.is-lit) text:not(.node-riddle), .js .ht-tree .node:not(.is-lit) .node-num-bg { opacity: 0; }
/* 수수께끼 문구는 반대로: 깨어나기 전에만 보이고 켜지면 사라집니다 */
.ht-tree .node-riddle { font: 500 9.5px var(--font-sans, Pretendard, sans-serif); letter-spacing: .02em; fill: #cfcfd6; text-anchor: middle; pointer-events: none; transition: opacity .5s ease-out; }
.ht-tree .node.is-lit .node-riddle, .js:not(.js) .node-riddle { opacity: 0; }
.js .hero-tree:not(.is-laid) .ht-tree .path-badge { opacity: 0 !important; }
/* 넓은 화면: 소개 글이 화면 왼쪽 끝에 붙어 나무와 멀어지지 않도록, 나무 쪽(오른쪽)으로 붙여 둡니다 */
@media (min-width: 1024px) { .hero-tree .ht-copy { justify-self: end; padding-right: clamp(40px, 5vw, 96px); } }
/* 호드 감사 크레딧: 영화 엔딩 크레딧처럼 가운데 정렬된 이름들 */
.hod-credits { width: min(1120px, calc(100% - 2 * clamp(20px, 5vw, 64px))); margin: clamp(64px, 9vw, 120px) auto 0; padding-top: 48px; border-top: 1px solid rgb(255 255 255 / .08); text-align: center; }
.hod-credits-title { margin: 0 0 28px; color: var(--sc); font-size: 11px; letter-spacing: .32em; }
.hod-credits ul { display: flex; flex-wrap: wrap; justify-content: center; gap: 14px 36px; margin: 0; padding: 0; list-style: none; }
.hod-credits li { color: var(--text, #fafafa); font-size: clamp(15px, 1.4vw, 19px); font-weight: 500; letter-spacing: .02em; opacity: .85; transition: opacity .3s, color .3s; }
.hod-credits li:hover { opacity: 1; color: var(--sc); }
.hod-credits-note { margin: 32px 0 0; color: var(--text-3, #8a8a94); font-size: 13px; }
/* ── 저사양(lite) 모드: 비싼 효과를 끕니다 ── */
.lite .image-mirror { animation: none; }
.lite .project-cover img, .lite .orb-art img, .lite .chapter-emblem img, .lite .artwork-card img { -webkit-box-reflect: none !important; }
.lite .ht-backdrop *, .lite .ht-captions .cap-runes, .lite .star, .lite .stars * { animation: none !important; }
.lite .image-mirror img { filter: none !important; }
/* ── 티페레트 갤러리: 그림이 많아도 한눈에 보이는 바둑판 + 크게 보기(라이트박스) ── */
.s-tiferet .artwork-grid { grid-template-columns: repeat(auto-fill, minmax(clamp(140px, 17vw, 220px), 1fr)); gap: clamp(10px, 1.4vw, 18px); padding-top: 24px; }
.s-tiferet .artwork-card { position: relative; }
.s-tiferet .artwork-frame { height: auto; aspect-ratio: 1 / 1; max-height: none; border-radius: 14px; overflow: hidden; cursor: zoom-in; }
.s-tiferet .artwork-frame > img { width: 100%; height: 100%; max-height: none; object-fit: cover; object-position: center; }
.s-tiferet .artwork-frame::after { display: none; }
.s-tiferet .artwork-card .image-mirror { display: none !important; } /* 바둑판에서는 반사를 빼서 그림끼리 겹쳐 보이지 않게 */
.s-tiferet .artwork-card figcaption { gap: 8px; padding-top: 8px; font-size: 12px; overflow: hidden; white-space: nowrap; }
.s-tiferet .artwork-card figcaption span:last-child { overflow: hidden; text-overflow: ellipsis; }
@media (max-width: 560px) { .s-tiferet .artwork-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* ── 말쿠트 연락: 왼쪽은 메시지와 메일 버튼, 오른쪽은 연락처 카드 한 장으로 정리 ── */
.s-malkuth .seph-body { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: clamp(28px, 4vw, 64px); align-items: start; }
.s-malkuth .contact-stage { display: block; grid-row: span 2; }
.s-malkuth .contact-orbit { display: none; }
.s-malkuth .contact-copy .section-title { font-size: clamp(28px, 3.2vw, 44px); line-height: 1.25; }
.s-malkuth .contact-intro { margin-top: 18px; color: #d4d4d8; font-size: 16px; line-height: 1.8; }
.s-malkuth .contact-send { display: inline-flex; align-items: center; gap: 12px; margin-top: 28px; min-height: 52px; padding: 0 24px; border: 1px solid var(--sc); border-radius: 999px; color: #fafafa; text-decoration: none; font-size: 15px; font-weight: 600; background: color-mix(in oklab, var(--sc) 14%, transparent); }
.s-malkuth .contact-address, .s-malkuth .contact-links { margin: 0; border: 1px solid rgb(255 255 255 / .1); background: rgb(18 18 22 / .72); }
.s-malkuth .contact-address { display: grid !important; grid-template-columns: 1fr !important; gap: 12px; padding: 24px; border-radius: 16px 16px 0 0; border-bottom: 0; }
.s-malkuth .contact-address > .mono { color: var(--sc); font-size: 11px; letter-spacing: .2em; }
.s-malkuth .contact-address a { color: #fafafa; font-size: clamp(16px, 1.6vw, 20px); font-weight: 600; overflow-wrap: anywhere; word-break: normal; text-decoration: none; }
.s-malkuth .contact-address button { justify-self: start; min-height: 40px; padding: 0 16px; border: 1px solid rgb(255 255 255 / .16); border-radius: 999px; background: transparent; color: #d4d4d8; cursor: pointer; }
.s-malkuth .contact-links { list-style: none; padding: 8px 12px 12px; border-radius: 0 0 16px 16px; }
.s-malkuth .contact-links a { display: grid; grid-template-columns: 96px 1fr auto; align-items: center; gap: 12px; min-height: 56px; padding: 0 12px; border-top: 1px solid rgb(255 255 255 / .06); border-radius: 10px; color: #fafafa; text-decoration: none; }
.s-malkuth .contact-links li:first-child a { border-top: 0; }
.s-malkuth .contact-links a:hover { background: rgb(255 255 255 / .05); }
.s-malkuth .contact-links .mono { color: var(--sc); font-size: 12px; }
@media (max-width: 860px) { .s-malkuth .seph-body { grid-template-columns: 1fr; } .s-malkuth .contact-stage { grid-row: auto; } }
/* 인트로: 로딩 막대 아래로 터미널 로그가 쌓이고 마지막에 Hello World! */
.intro { animation-delay: 4.6s !important; } /* 안전장치: 스크립트가 멈춰도 4.6초 뒤엔 인트로를 걷어냅니다 */
.intro-pct { color: var(--text, #fafafa); margin-left: 6px; font-variant-numeric: tabular-nums; }
.intro-hello { display: grid; align-content: start; gap: 4px; width: min(340px, 86vw); margin: 18px auto 0; text-align: left; font: 11px/1.5 var(--font-mono, ui-monospace, monospace); color: #8b8b96; min-height: 9em; }
.intro-log-line { opacity: 0; animation: log-in .25s ease forwards; white-space: pre; overflow: hidden; text-overflow: ellipsis; }
.intro-log-line.is-hello { color: #fafafa; }
.intro-log-line.is-hello::after { content: ''; display: inline-block; width: .6em; height: 1em; margin-left: 4px; vertical-align: -.15em; background: #b9a3e3; animation: hello-caret .9s steps(1) infinite; }
@keyframes log-in { from { opacity: 0; translate: 0 3px; } to { opacity: 1; translate: 0 0; } }
@keyframes hello-caret { 50% { opacity: 0; } }

/* 스크롤 힌트는 배경·선 없이 글자만 희미하게 */
.tree-hint { padding: 0 !important; background: none !important; border: 0 !important; }
.tree-hint span { font-weight: 500 !important; font-size: 13px !important; color: rgb(250 250 250 / .45) !important; letter-spacing: .08em !important; }
.tree-hint-line { display: none !important; }
.tree-hint.is-shown span { animation: hint-breathe 2.6s ease-in-out infinite; }
@keyframes hint-breathe { 50% { opacity: .55; } }
/* 갤러리 바둑판에도 아래 반사: 그림 칸 전체를 아래로 옅게 비춥니다 (box-reflect, 크롬·사파리·엣지) */
.s-tiferet .artwork-card .image-mirror { display: none !important; }
.s-tiferet .artwork-frame { -webkit-box-reflect: below 4px linear-gradient(to bottom, transparent 82%, rgb(0 0 0 / .28)); }
.s-tiferet .artwork-card { padding-bottom: 20%; } /* 아래 반사가 들어갈 자리 */
.s-tiferet .artwork-card figcaption { position: absolute; inset: 0 0 auto 0; aspect-ratio: 1 / 1; display: flex; align-items: flex-end; margin: 0; padding: 10px 12px !important; border-radius: 14px; background: linear-gradient(to bottom, transparent 68%, rgb(5 4 8 / .72)); color: #fafafa !important; pointer-events: none; } /* 제목은 그림 아래쪽 위에 겹쳐 표시 */
.lite .s-tiferet .artwork-frame { -webkit-box-reflect: none; }
.lite .s-tiferet .artwork-card { padding-bottom: 0; }
/* 말쿠트 연락 카드: 주소 카드와 링크 카드를 각각 완전한 둥근 카드로 (잘려 보이지 않게) */
.s-malkuth .contact-address { border-radius: 16px !important; border-bottom: 1px solid rgb(255 255 255 / .1) !important; }
.s-malkuth .contact-links { border-radius: 16px !important; padding: 6px !important; }
.s-malkuth .contact-links a { border-top: 0 !important; }
.s-malkuth .contact-links li + li a { box-shadow: 0 -1px 0 rgb(255 255 255 / .06); border-radius: 0 0 10px 10px; }
/* ── 말쿠트 개선: 함께할 일 칩 + 지나온 여정(열 세피라) + 처음으로 돌아가기 ── */
.s-malkuth .contact-topics { display: flex; flex-wrap: wrap; gap: 8px; margin: 22px 0 0; padding: 0; list-style: none; }
.s-malkuth .contact-topics li { padding: 7px 14px; border: 1px solid rgb(255 255 255 / .12); border-radius: 999px; color: #d4d4d8; font-size: 13px; background: rgb(255 255 255 / .03); }
.s-malkuth .contact-send { transition: background .25s, transform .2s; }
.s-malkuth .contact-send:hover { background: color-mix(in oklab, var(--sc) 26%, transparent); transform: translateY(-2px); }
.s-malkuth .contact-address button { transition: border-color .2s, color .2s; }
.s-malkuth .contact-address button:hover { border-color: var(--sc); color: #fafafa; }
/* 여정의 끝: 왼쪽에 가로로 누운 작은 생명의 나무(열 세피라 모두 켜짐), 오른쪽에 마무리 문구와 돌아가기 버튼 */
.malkuth-journey { grid-column: 1 / -1; margin-top: clamp(48px, 7vw, 96px); padding: clamp(24px, 3.4vw, 44px); display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); gap: clamp(24px, 4vw, 56px); align-items: center; border: 1px solid rgb(255 255 255 / .09); border-radius: 22px; background: linear-gradient(135deg, rgb(255 255 255 / .035), rgb(255 255 255 / .01)); }
.journey-tree { width: 100%; height: auto; overflow: visible; }
.journey-tree line { stroke: rgb(255 255 255 / .16); stroke-width: 1.5; }
.journey-tree a { outline: none; }
.journey-tree .jt-dot { fill: color-mix(in oklab, var(--sc) 22%, #0b0b0e); stroke: var(--sc); stroke-width: 2.2; transition: transform .3s cubic-bezier(.34,1.56,.64,1), fill .25s; transform-box: fill-box; transform-origin: center; }
.journey-tree .jt-num { fill: #fafafa; font: 600 15px var(--font-mono, ui-monospace, monospace); text-anchor: middle; pointer-events: none; }
.journey-tree .jt-halo { fill: none; stroke: var(--sc); stroke-width: 1.2; opacity: .45; animation: jt-pulse 2.8s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
.journey-tree a:hover .jt-dot, .journey-tree a:focus-visible .jt-dot { transform: scale(1.18); fill: color-mix(in oklab, var(--sc) 45%, #0b0b0e); }
@keyframes jt-pulse { 50% { transform: scale(1.18); opacity: .15; } }
.journey-end { text-align: left; }
.journey-end .mono { margin: 0; color: var(--sc); font-size: 11px; letter-spacing: .24em; }
.journey-line { margin: 14px 0 0; color: #fafafa; font-size: clamp(18px, 1.8vw, 24px); font-weight: 600; line-height: 1.5; word-break: keep-all; }
.journey-return { display: inline-flex; align-items: center; gap: 10px; margin-top: 26px; min-height: 48px; padding: 0 22px; border: 1px solid var(--sc); border-radius: 999px; color: #fafafa; text-decoration: none; font-size: 14px; background: color-mix(in oklab, var(--sc) 12%, transparent); transition: background .2s, transform .2s; }
.journey-return:hover { background: color-mix(in oklab, var(--sc) 24%, transparent); transform: translateY(-2px); }
@media (max-width: 760px) { .malkuth-journey { grid-template-columns: 1fr; } .journey-end { text-align: center; } }
@media (prefers-reduced-motion: reduce) { .journey-tree .jt-halo { animation: none; } }
.s-malkuth .contact-links a { display: grid !important; grid-template-columns: 88px minmax(0, 1fr) 20px !important; grid-template-rows: auto !important; grid-auto-flow: column !important; align-items: center !important; }
.s-malkuth .contact-links a > * { margin: 0 !important; }
.s-malkuth .contact-links a > span { grid-column: auto !important; grid-row: auto !important; } /* 모바일 2줄 배치 규칙을 무시하고 한 줄로 */
/* 소리 버튼: 글자 대신 아이콘. 켜짐/꺼짐은 aria-pressed로 아이콘 모양을 바꿉니다 (음표에 사선 / 스피커 물결 ↔ X) */
.audio-controls .music-control, .audio-controls .sound-control { width: 44px; min-width: 44px; justify-content: center; padding: 0 !important; gap: 0 !important; }
.audio-controls .music-wave { display: none; }
.ac-icon { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.music-control .ac-slash { opacity: 1; transition: opacity .2s; }
.music-control[aria-pressed="true"] .ac-slash { opacity: 0; }
.music-control[aria-pressed="true"] { color: var(--text, #fafafa); }
.sound-control .ac-off { display: none; }
.sound-control[aria-pressed="false"] .ac-on { display: none; }
.sound-control[aria-pressed="false"] .ac-off { display: inline; }
/* 미니맵: 케테르 장부터 오른쪽에서 살짝 밀려 들어오며 나타납니다 */
.minimap { transition: opacity .6s ease, translate .7s cubic-bezier(.16,1,.3,1) !important; }
.minimap:not(.is-shown) { opacity: 0 !important; translate: 24px 0; pointer-events: none !important; }
/* ── 연출 보강 ── */
/* 장 제목: 아래에서 위로 걷히며 드러남 (clip-path) */
/* 연대기 항목: 차례로 떠오름 */
.fx-rise { opacity: 0; translate: 0 14px; transition: opacity .6s ease, translate .7s cubic-bezier(.16,1,.3,1); }
.fx-rise.is-shown { opacity: 1; translate: 0 0; }
/* 기록 숫자는 자릿수가 바뀌어도 흔들리지 않게 */
.bi-stats dd { font-variant-numeric: tabular-nums; }
/* 캐릭터 원: 장이 보이는 동안 천천히 떠다니며 숨 쉬기 */
.chapter.is-in-view .orb { animation: orb-float 6s ease-in-out infinite; }
@keyframes orb-float { 50% { translate: 0 -6px; } }
/* 상단 읽기 진행 막대: 지금 장의 색으로 */
.topbar[data-seph="1"] ~ .reading-progress { background: var(--c1); } .topbar[data-seph="2"] ~ .reading-progress { background: var(--c2); }
.topbar[data-seph="3"] ~ .reading-progress { background: var(--c3); } .topbar[data-seph="4"] ~ .reading-progress { background: var(--c4); }
.topbar[data-seph="5"] ~ .reading-progress { background: var(--c5); } .topbar[data-seph="6"] ~ .reading-progress { background: var(--c6); }
.topbar[data-seph="7"] ~ .reading-progress { background: var(--c7); } .topbar[data-seph="8"] ~ .reading-progress { background: var(--c8); }
.topbar[data-seph="9"] ~ .reading-progress { background: var(--c9); } .topbar[data-seph="10"] ~ .reading-progress { background: var(--c10); }
.reading-progress { transition: background .6s ease; }
/* 프로젝트·도구 항목: 마우스를 올리면 살짝 떠오름 */
.project-entry > summary, .hod-credits li { transition: translate .25s cubic-bezier(.34,1.56,.64,1); }
.project-entry > summary:hover { translate: 4px 0; }
.lite .chapter.is-in-view .orb { animation: none; }
@media (prefers-reduced-motion: reduce) { .fx-wipe, .fx-rise { clip-path: none; opacity: 1; translate: none; } .chapter.is-in-view .orb { animation: none; } }
/* 세피라 별칭: 장 제목 바로 위, 장 색으로 아주 담담하게 */
.chapter-epithet { margin: 14px 0 6px; font-size: clamp(.95rem, .85rem + .4vw, 1.15rem); letter-spacing: .04em; color: var(--sc, var(--text-2)); opacity: .85; }
/* 클리포트의 나무: 세피로트와 같은 배치, 핏빛 그림자 톤 */
.qliphoth { --q: #c0392b; position: relative; overflow: hidden; padding: clamp(140px, 18vw, 240px) clamp(16px, 4vw, 48px) clamp(80px, 10vw, 140px); background: linear-gradient(to bottom, transparent 0, rgb(30 3 5 / .7) 22%, rgb(10 1 2 / .96) 60%); text-align: center; }
.qliphoth.is-awake .q-head { position: relative; margin-bottom: clamp(24px, 4vw, 48px); }
.q-latin { margin: 0; font-family: var(--font-mono, monospace); font-size: clamp(2.6rem, 1rem + 7vw, 7rem); font-weight: 600; letter-spacing: .5em; text-indent: .5em; line-height: 1; color: transparent; -webkit-text-stroke: 1px rgb(192 57 43 / .55); opacity: 0; transform: translateY(-24px); transition: opacity 1.6s ease, transform 1.8s cubic-bezier(.16, 1, .3, 1), letter-spacing 2.4s cubic-bezier(.16, 1, .3, 1); }
.qliphoth.is-awake .q-latin { opacity: 1; transform: none; letter-spacing: .22em; text-indent: .22em; }
.q-title { margin: 18px 0 0; font-size: clamp(1.5rem, 1rem + 2vw, 2.6rem); letter-spacing: -.02em; color: #fafafa; clip-path: inset(0 50% 0 50%); transition: clip-path 1.2s .5s cubic-bezier(.16, 1, .3, 1); }
.qliphoth.is-awake .q-title { clip-path: inset(0 0 0 0); }
.q-sub { margin: 12px 0 0; font-size: 14px; color: var(--text-3, #8a8a93); opacity: 0; transition: opacity 1s 1s; }
.qliphoth.is-awake .q-sub { opacity: 1; }
.q-tree { display: block; width: min(560px, 100%); margin: 0 auto; overflow: visible; }
.q-paths line { stroke: rgb(192 57 43 / .22); stroke-width: 2; stroke-dasharray: 260; stroke-dashoffset: 260; transition: stroke-dashoffset 2.2s .8s ease; }
.qliphoth.is-awake .q-paths line { stroke-dashoffset: 0; }
.qliphoth.is-awake .q-ring { fill: rgb(12 2 3 / .95); stroke: rgb(255 255 255 / .12); stroke-width: 1.6; transition: fill .3s; }
.q-lock { fill: none; stroke: rgb(255 255 255 / .25); stroke-width: 1.6; stroke-linejoin: round; }
.q-num-bg { fill: rgb(12 2 3); stroke: rgb(255 255 255 / .14); }
.q-num { fill: var(--text-3, #8a8a93); font-size: 10px; text-anchor: middle; font-family: var(--font-mono, monospace); }
.q-sym { fill: #ff8a7a; font-size: 16px; text-anchor: middle; }
.q-name { fill: #fafafa; font-size: 13px; font-weight: 600; text-anchor: middle; }
.q-node.is-open .q-ring { stroke: var(--q); stroke-width: 2.6; fill: rgb(70 8 10 / .95); animation: q-beat 3.2s ease-in-out infinite; }
.q-node.is-open .q-num-bg { stroke: var(--q); }
.q-node.is-open .q-num { fill: #ff8a7a; }
.q-node.is-open:hover .q-ring, .q-node.is-open:focus-visible .q-ring { fill: rgb(100 12 14 / .95); }
.q-node.is-open:focus-visible { outline: none; }
.q-node.is-open:focus-visible .q-ring { stroke: #fafafa; }
@keyframes q-beat { 50% { stroke-opacity: .4; } }
.q-epithet { margin: 0; font-size: 14px; letter-spacing: .04em; color: #ff8a7a; }
.q-card h3 { margin: 6px 0 0; font-size: 1.4rem; font-weight: 600; color: #fafafa; }
.q-card h3 .mono { font-size: 12px; color: var(--text-3, #8a8a93); letter-spacing: .08em; }
.q-desc { margin: 14px 0 0; color: var(--text-2, #a1a1aa); line-height: 1.75; word-break: keep-all; }
.q-sealed { margin: 18px 0 0; font-size: 11px; letter-spacing: .06em; color: var(--text-3, #8a8a93); }
@keyframes q-flash { from { background: rgb(192 57 43 / .5); } }
/* 하강 장막: 클리포트에 가까워질수록 화면 전체가 붉게 어두워집니다 (main.js가 --qd 0~1 갱신) */
.q-veil { position: fixed; inset: 0; pointer-events: none; z-index: 1; background: radial-gradient(ellipse at 50% 120%, rgb(120 10 12 / .5), rgb(0 0 0 / .85) 70%); opacity: calc(var(--qd, 0) * .6); }
.qliphoth > * { position: relative; z-index: 2; }
@media (prefers-reduced-motion: reduce) { .qliphoth *, .q-veil { transition: none !important; animation: none !important; } .q-node, .q-sub, .q-latin { opacity: 1; } .q-title { clip-path: none; } .q-paths line { stroke-dashoffset: 0; } }
/* 클리포트 연출 2 */
.q-ash { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 1 !important; pointer-events: none; }
.q-signal { stroke: #ff6a55; stroke-width: 2.4; stroke-linecap: round; stroke-dasharray: 10 var(--len); stroke-dashoffset: 10; opacity: 0; }
.qliphoth.is-awake .q-signal { animation: q-flow 4.8s linear infinite; }
@keyframes q-flow { 0% { stroke-dashoffset: 10; opacity: 0; } 8% { opacity: 1; } 55% { stroke-dashoffset: calc(var(--len) * -1); opacity: .9; } 56%, 100% { opacity: 0; stroke-dashoffset: calc(var(--len) * -1); } }
.q-ripple { fill: none; stroke: #c0392b; stroke-width: 1.5; transform-box: fill-box; transform-origin: center; opacity: 0; }
.qliphoth.is-awake .q-ripple { animation: q-ripple 3.2s cubic-bezier(.16, 1, .3, 1) infinite; }
@keyframes q-ripple { 0% { transform: scale(1); opacity: .7; } 100% { transform: scale(2.1); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .q-signal, .q-ripple { display: none; } }
/* 클리포트 점등: 세피로트 나무와 같은 문법 — 처음엔 흰 실루엣, 차례로 켜지며 제 색을 찾습니다 */
.q-latin { letter-spacing: .22em !important; text-indent: .22em !important; }
.q-title { clip-path: none; opacity: 0; translate: 0 12px; transition: opacity 1s .3s, translate 1s .3s cubic-bezier(.16, 1, .3, 1); }
.qliphoth.is-awake .q-title { opacity: 1; translate: 0 0; }
.q-node .q-ring { fill: transparent; stroke: rgb(255 255 255 / .28); }
.q-node .q-lock, .q-node .q-num, .q-node .q-num-bg, .q-node .q-sym, .q-node .q-name { opacity: 0; transition: opacity .5s; }
.q-node.is-lit .q-lock, .q-node.is-lit .q-num, .q-node.is-lit .q-num-bg, .q-node.is-lit .q-sym, .q-node.is-lit .q-name { opacity: 1; }
.q-node.is-lit .q-ring { fill: rgb(12 2 3 / .95); stroke: rgb(255 255 255 / .12); animation: q-lit .9s cubic-bezier(.34, 1.56, .64, 1) both; }
.q-node.is-open.is-lit .q-ring { fill: rgb(70 8 10 / .95); stroke: var(--q); stroke-width: 2.6; animation: q-lit .9s cubic-bezier(.34, 1.56, .64, 1) both, q-beat 3.2s 1s ease-in-out infinite; }
@keyframes q-lit { 0% { stroke: #fff; stroke-width: 1.5; } 35% { fill: rgb(192 57 43 / .45); stroke: #ff8a7a; stroke-width: 3.5; } }
.q-node.is-open:not(.is-lit) { pointer-events: none; }
.q-paths line { transition: stroke-dashoffset 1.6s ease; }
.qliphoth.is-awake .q-paths line { stroke-dashoffset: 260; }
.qliphoth.is-traced .q-paths line { stroke-dashoffset: 0; }
.q-signal { visibility: hidden; } .qliphoth.is-traced .q-signal { visibility: visible; }
.q-ripple { visibility: hidden; } .qliphoth.is-traced .q-ripple { visibility: visible; }
.q-chapters { opacity: 0; translate: 0 16px; transition: opacity .8s, translate .8s cubic-bezier(.16, 1, .3, 1); }
.qliphoth.is-traced .q-chapters { opacity: 1; translate: 0 0; }
.q-ash { opacity: .55; }
@media (prefers-reduced-motion: reduce) { .q-node.is-lit .q-ring { animation: none; } .q-title, .q-chapters { opacity: 1; translate: none; } }
/* 가말리엘: 플레이 가능한 게임 목록 */
.game-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 14px; margin: 22px 0 6px; text-align: left; }
.game-card { display: grid; gap: 10px; color: inherit; text-decoration: none; border-radius: 14px; }
.game-cover { position: relative; display: block; aspect-ratio: 4 / 5; overflow: hidden; border-radius: 14px; border: 1px solid rgb(255 255 255 / .08); background: #0c0203; }
.game-cover img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s cubic-bezier(.16, 1, .3, 1), filter .6s; filter: saturate(.85); }
.game-cover-fallback { position: absolute; inset: 0; display: grid; place-items: center; font-size: 28px; color: #ff8a7a; }
.game-play { position: absolute; left: 10px; bottom: 10px; padding: 6px 10px; border-radius: 999px; font-size: 11px; letter-spacing: .06em; background: rgb(10 2 3 / .8); border: 1px solid rgb(192 57 43 / .6); color: #fafafa; clip-path: inset(0 100% 0 0 round 999px); transition: clip-path .45s cubic-bezier(.16, 1, .3, 1); }
.game-card:hover .game-cover img, .game-card:focus-visible .game-cover img { transform: scale(1.04); filter: saturate(1.1); }
.game-card:hover .game-play, .game-card:focus-visible .game-play { clip-path: inset(0 0 0 0 round 999px); }
.game-card:hover .game-cover, .game-card:focus-visible .game-cover { border-color: rgb(192 57 43 / .7); }
.game-card:focus-visible { outline: 2px solid #fafafa; outline-offset: 3px; }
.game-info { display: grid; grid-template-columns: auto 1fr; column-gap: 10px; align-items: baseline; }
.game-info b { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.game-idx { font-size: 11px; color: var(--text-3, #8a8a93); }
.game-desc { grid-column: 2; font-size: 13px; color: var(--text-2, #a1a1aa); }
.games-empty { grid-column: 1 / -1; color: var(--text-3, #8a8a93); text-align: center; }
.game-admin-btn { margin-top: 14px; }
/* 게임 관리 대화상자 */
.gm-x { width: 44px; height: 44px; border: 0; background: transparent; color: inherit; font-size: 16px; cursor: pointer; }
.gm-body { display: grid; gap: 22px; padding: 20px 24px 26px; text-align: left; }
.gm-body h4 { margin: 0 0 10px; font-size: 14px; font-weight: 600; }
.gm-hint, .gm-scan, .gm-status { margin: 0; font-size: 13px; color: var(--text-2, #a1a1aa); line-height: 1.6; word-break: keep-all; }
.gm-scan[data-bad] { color: #ff8a7a; }
.gm-form { display: grid; gap: 12px; }
.gm-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.gm-field { display: grid; gap: 6px; font-size: 13px; color: var(--text-2, #a1a1aa); }
.gm-field input { min-height: 40px; padding: 8px 12px; border: 1px solid rgb(255 255 255 / .1); border-radius: 8px; background: #0b0b0e; color: #fafafa; font: inherit; }
.gm-field input:focus-visible { outline: none; border-color: #a1a1aa; }
.gm-check { display: flex; gap: 8px; align-items: center; font-size: 13px; color: var(--text-2, #a1a1aa); margin-top: 8px; }
.gm-go { min-height: 44px; border: 0; border-radius: 10px; background: #fafafa; color: #0b0b0e; font-weight: 600; cursor: pointer; }
.gm-go:disabled { opacity: .5; cursor: progress; }
.gm-list ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.gm-list li { display: grid; grid-template-columns: 1fr auto auto; gap: 12px; align-items: center; padding: 10px 12px; border: 1px solid rgb(255 255 255 / .06); border-radius: 10px; }
.gm-list li a { color: inherit; } .gm-list li .mono { font-size: 11px; color: var(--text-3, #8a8a93); }
.gm-del { min-height: 36px; padding: 0 12px; border: 1px solid rgb(255 90 78 / .4); border-radius: 8px; background: transparent; color: #ff8a7a; cursor: pointer; }
.gm-empty { color: var(--text-3, #8a8a93); }
/* 클리파 장: 세피라 장과 같은 머리 구조(번호·이름·뜻 / 별칭 / 큰 문장 / 역할 / 설명), 색만 핏빛 */
.q-chapters { max-width: 1120px; margin: clamp(56px, 8vw, 112px) auto 0; text-align: left; display: grid; gap: clamp(72px, 10vw, 140px); }
.q-card { --sc: #ff6a55; padding-top: clamp(28px, 4vw, 44px); border-top: 1px solid rgb(192 57 43 / .28); scroll-margin-top: 96px; }
.q-card .chapter-kicker { display: flex; flex-wrap: wrap; gap: 14px; align-items: baseline; margin: 0; color: var(--text-2, #a1a1aa); font-size: 14px; }
.q-card .chapter-index { color: var(--sc); }
.q-card .chapter-meaning { color: var(--sc); border-bottom: 1px solid currentColor; padding-bottom: 2px; }
.q-card .chapter-statement { max-width: 17em; margin: 18px 0 0; font-size: clamp(28px, 3.4vw, 46px); line-height: 1.35; letter-spacing: -.05em; font-weight: 500; color: #fafafa; text-wrap: balance; word-break: keep-all; }
.q-card .chapter-role { margin: 26px 0 0; color: var(--sc); font-size: 14px; }
.q-card .chapter-connection { max-width: 38em; margin: 10px 0 0; color: var(--text-2, #a1a1aa); line-height: 1.75; word-break: keep-all; }
.q-card:target .chapter-statement { animation: q-flash-text 1.4s ease-out; }
@keyframes q-flash-text { from { color: #ff8a7a; } }
.q-chapters .q-sealed { text-align: center; }
.q-card .game-grid { margin-top: 32px; }
.qliphoth { z-index: 2; } /* 붉은 장막(q-veil) 위로 내용이 올라오게 */
/* 장막은 배경층으로만: 본문(main)보다 아래에 깔려 글자를 흐리지 않습니다 */
.q-veil { z-index: 0; }
main#main { position: relative; z-index: 1; }
/* 클리포트 경로: 노드가 켜지는 동안 타우미엘에서 아래로 한 줄씩 그어집니다 (선 길이·지연은 main.js가 --plen/--pdl로 지정) */
.qliphoth .q-paths line:not(.q-signal) { stroke-dasharray: var(--plen, 260); stroke-dashoffset: var(--plen, 260); transition: stroke-dashoffset .9s cubic-bezier(.65, 0, .35, 1) var(--pdl, 0s); }
.qliphoth.is-awake .q-paths line:not(.q-signal) { stroke-dashoffset: 0; }
@media (prefers-reduced-motion: reduce) { .qliphoth .q-paths line:not(.q-signal) { stroke-dashoffset: 0; transition: none; } }
