/* 입구 화면(입구 PIN·기기 승인·PC PIN) — 스토리지 입구와 같은 공간.
   어두운 강판 사이로 푸른 빛 하나, 이름을 품은 전원 고리, 무광 철판 숫자판. */
@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css");

.vault-screen, .approve-box {
  --vh: 1vh;    /* 옛 브라우저용 */
}
/* 폰 브라우저의 vh 는 주소창·아래 막대가 사라졌을 때 높이다. 막대가 떠 있으면 그만큼 모자라 고리가 로고 쪽으로 밀린다 */
@supports (height: 1dvh) {
  .vault-screen, .approve-box { --vh: 1dvh; }
}
.vault-screen {
  --vault-light: 150, 205, 245;
  position: fixed; inset: 0; z-index: 20; overflow: hidden; color: #F1F4F7;
  background: #06080b radial-gradient(60% 46% at 50% 27%, rgba(40, 92, 130, .5), rgba(12, 24, 34, .5) 58%, rgba(6, 8, 11, 0) 100%);
  font-family: "Pretendard Variable", Pretendard, -apple-system, "Malgun Gothic", sans-serif;
  -webkit-user-select: none; user-select: none;
}
.vault-screen input { -webkit-user-select: text; user-select: text; }
/* 열린 문의 양쪽 끝 강판 */
.vault-leaf { position: absolute; top: 0; bottom: 0; width: 6px; background: #1f2226 url(/steel.webp) center/cover; }
.vault-leaf.left { left: 0; border-right: 1px solid rgba(255, 255, 255, .2); }
.vault-leaf.right { right: 0; border-left: 1px solid rgba(255, 255, 255, .2); }
/* 고리와 숫자판은 한 덩어리로 화면 가운데에 모은다. 위아래 끝으로 벌리면 큰 화면에서 서로 멀어진다 */
.vault-page {
  height: 100%; overflow: hidden; overflow: clip;  /* hidden 만 쓰면 빛 번짐 때문에 포커스가 판을 옆으로 밀어 낸다 */
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: calc(48px + env(safe-area-inset-top)) max(16px, env(safe-area-inset-right)) calc(20px + env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
}
.vault-logo { position: absolute; left: 20px; top: calc(18px + env(safe-area-inset-top)); height: 26px; width: auto; opacity: .85; }
.vault-close {
  position: absolute; right: 16px; top: calc(14px + env(safe-area-inset-top)); width: 38px; height: 38px; display: grid; place-items: center;
  border: 0; border-radius: 9px; background: rgba(255, 255, 255, .07); color: #DCE5EC; cursor: pointer;
}
.vault-close svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; }

/* 전원 고리: 한 줄이 자릿수만큼 늘어난다. 조각으로 나누면 이음매마다 끊기고 빛이 겹쳐 보인다 */
.power { position: relative; pointer-events: none; flex: none; width: min(68vw, calc(34 * var(--vh))); aspect-ratio: 1; container-type: inline-size; }
.power::before {
  content: ""; position: absolute; inset: -46%; border-radius: 50%; opacity: calc(.3 + var(--level, 0) * .7); transition: opacity .25s;
  background: radial-gradient(circle, rgba(var(--vault-light), .24), rgba(var(--vault-light), 0) 62%);
}
.power svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; fill: none; stroke-linecap: round; stroke-width: 2.6; }
.ring-off { stroke: rgba(255, 255, 255, .1); }
.ring-fill, .ring-bar {
  stroke: rgb(186, 226, 250); opacity: 0;
  filter: drop-shadow(0 0 4px rgba(var(--vault-light), .95)) drop-shadow(0 0 13px rgba(var(--vault-light), .55));
}
.ring-fill { stroke-dasharray: 0 100; transition: stroke-dasharray .22s cubic-bezier(.2, .7, .2, 1), opacity .12s; }
.ring-bar { transition: opacity .09s; }
.ring-fill.on, .ring-bar.on { opacity: 1; }
/* PIN 오류: 고리 전체와 둘레 빛이 잠깐 붉어졌다 사라진다. 바로 다시 쳐도 되도록 파란 고리와 따로 그린다 */
.ring-deny {
  stroke: rgb(255, 128, 132); opacity: 0;
  filter: drop-shadow(0 0 4px rgba(255, 70, 80, .95)) drop-shadow(0 0 14px rgba(255, 60, 70, .6));
}
.power::after {
  content: ""; position: absolute; inset: -46%; border-radius: 50%; opacity: 0;
  background: radial-gradient(circle, rgba(255, 64, 74, .34), rgba(255, 64, 74, 0) 62%);
}
.power.denied .ring-deny, .power.denied::after { animation: vault-deny .8s ease-out; }
/* 붉은빛이 도는 동안은 숫자판도 반응하지 않는다 */
.power.denied ~ .vault-pad { pointer-events: none; }
@keyframes vault-deny { 0%, 42% { opacity: 1; } 100% { opacity: 0; } }
.vault-name { position: absolute; inset: 0; z-index: 1; display: grid; place-content: center; justify-items: center; text-align: center; }
.vault-name p { margin: 0; font-size: 3.7cqw; font-weight: 700; letter-spacing: .24em; padding-left: .24em; color: rgb(var(--vault-light)); white-space: nowrap; }
.vault-name h1 { margin: 2cqw 0 0; font-size: 14cqw; font-weight: 800; letter-spacing: -.035em; white-space: nowrap; }

.vault-msg { min-height: 20px; margin: 6px 0; font-size: 13px; color: #FF8A8F; text-align: center; word-break: keep-all; }

/* 철판 숫자판: 누른 단추가 틀째 쿵 흔들리고, 안쪽 판은 눌렸다 바로 튀어 오른다 */
/* 폰 단추 약 92x57: 터치 기준(44pt·48dp)을 넘기면서 양옆에 여백이 남는 크기 */
.vault-pad { width: min(76vw, max(300px, calc(38 * var(--vh)))); container-type: inline-size; }
/* 연속으로 틀려 기다리는 동안: 눌리지 않고 꺼진 듯 어둡다 */
.vault-pad { transition: opacity .2s; }
.vault-pad.locked { pointer-events: none; opacity: .35; }
.keys { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2.8cqw; }
.slot {
  position: relative; display: block; width: 100%; aspect-ratio: 8/5; border: 0; padding: 1px; background: #020305; border-radius: 9px;
  box-shadow: inset 0 2px 3px #000, 0 1px 0 rgba(255, 255, 255, .07); cursor: pointer; touch-action: manipulation; font: inherit; color: inherit;
}
.slot:focus-visible { outline: 2px solid rgb(var(--vault-light)); outline-offset: 2px; }
.slot::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; opacity: 0; pointer-events: none;
  box-shadow: inset 0 0 0 2px rgba(var(--vault-light), .95), 0 0 16px rgba(var(--vault-light), .5), inset 0 0 8px 1px rgba(var(--vault-light), .75);
}
.slot.hit::after { animation: vault-flare .3s ease-out; }
.slot.hit { animation: vault-thud .2s ease-out; }
.slot.down { z-index: 2; }
.plate {
  position: relative; display: grid; place-items: center; width: 100%; height: 100%; background: center/100% 100% no-repeat; border-radius: 8px;
  transition: transform .12s cubic-bezier(.3, 1.7, .5, 1), filter .1s;
}
.plate.p0 { background-image: url(/plate_0.webp); }
.plate.p1 { background-image: url(/plate_1.webp); }
.plate.p2 { background-image: url(/plate_2.webp); }
.plate.p3 { background-image: url(/plate_3.webp); }
.plate::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; opacity: 0; transition: opacity .1s;
  background: linear-gradient(180deg, rgba(0, 0, 0, .7), rgba(0, 0, 0, 0) 40%);
}
.slot.down .plate { transform: translateY(2px) scale(.962); filter: brightness(.72); transition: transform .04s, filter .04s; }
.slot.down .plate::after { opacity: 1; transition: opacity .04s; }
.plate b { position: relative; font-size: clamp(18px, 7cqw, 42px); font-weight: 500; letter-spacing: .01em; color: #DCE5EC; text-shadow: 0 -1px 0 rgba(0, 0, 0, .7), 0 1px 0 rgba(255, 255, 255, .1); }
.plate svg { position: relative; width: clamp(18px, 6.6cqw, 38px); height: clamp(18px, 6.6cqw, 38px); fill: none; stroke: #DCE5EC; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
@keyframes vault-thud {
  0% { transform: none; }
  18% { transform: translateY(4px) scale(.975); }
  36% { transform: translate(-3px, 2px) rotate(-.9deg) scale(.985); }
  54% { transform: translate(2.6px, 3px) rotate(.7deg) scale(.985); }
  72% { transform: translate(-1.6px, 1.5px) rotate(-.35deg); }
  88% { transform: translate(.8px, .8px); }
  100% { transform: none; }
}
@keyframes vault-flare { 0% { opacity: 0; } 15% { opacity: 1; } 100% { opacity: 0; } }

/* 기기 승인: 숫자판 자리에 요청 단추와 확인번호 */
/* 단추가 등록코드로 바뀌어도 고리가 움직이지 않게 높이를 잡아 둔다 */
.vault-gate { width: min(76vw, max(300px, calc(38 * var(--vh)))); min-height: 190px; padding-top: 14px; text-align: center; container-type: inline-size; }
.vault-gate p { margin: 0 0 18px; font-size: 14px; color: #A7B2BE; }
.device-code { font-size: 44px; font-weight: 700; letter-spacing: .14em; padding-left: .14em; margin: 0 0 14px; }
/* 등록코드: 철판 네 장에 숫자가 빛을 내며 새겨지고, 식으면 숫자판 글자와 같은 음각으로 남는다 */
.device-digits { display: flex; justify-content: center; gap: 2.8cqw; margin: 0 0 16px; }
.device-digit { width: 19cqw; aspect-ratio: 1/1.12; border-radius: 8px; box-shadow: 0 0 0 1px #020305, inset 0 1px 0 rgba(255, 255, 255, .06); }
.device-digit b { font-size: clamp(26px, 11cqw, 60px); font-weight: 600; letter-spacing: 0; color: #DCE5EC; text-shadow: 0 -1px 0 rgba(0, 0, 0, .85), 0 1px 0 rgba(255, 255, 255, .14); }
.device-digits.engrave b { animation: vault-engrave .62s cubic-bezier(.2, .7, .2, 1) both; }
@keyframes vault-engrave {
  0% { opacity: 0; transform: scale(1.55); filter: blur(6px); color: #fff; text-shadow: 0 0 22px rgb(var(--vault-light)); }
  34% { opacity: 1; transform: scale(.95); filter: blur(0); color: #fff; text-shadow: 0 0 8px rgb(var(--vault-light)), 0 0 26px rgba(var(--vault-light), .85); }
  100% { opacity: 1; transform: none; filter: blur(0); color: #DCE5EC; text-shadow: 0 -1px 0 rgba(0, 0, 0, .85), 0 1px 0 rgba(255, 255, 255, .14); }
}

.primary-btn { background: #E9EEF3; color: #0D1014; border: 0; border-radius: 10px; padding: 13px 22px; font: inherit; font-size: 15px; font-weight: 600; cursor: pointer; }
.primary-btn:disabled, .primary-btn.is-off { opacity: .5; cursor: default; }

/* 승인 화면(디스코드 링크로 여는 쪽) */
.approve-box { position: relative; max-width: 420px; margin: 0 auto; padding: calc(14 * var(--vh)) 20px 20px; text-align: center; }
.approve-box h1 { font-size: 22px; font-weight: 800; margin: 0 0 18px; }
.approve-box .sub { color: #A7B2BE; }
.approve-list { display: grid; grid-template-columns: auto 1fr; gap: 8px 14px; text-align: left; margin: 0 0 18px; padding: 14px 16px; font-size: 14px;
  background: rgba(13, 16, 20, .72); border: 1px solid rgba(255, 255, 255, .09); border-radius: 14px; }
.approve-list dt { color: #7D8793; }
.approve-list dd { margin: 0; word-break: break-all; }
.approve-name { display: block; margin: 0 0 6px; text-align: left; font-size: 13px; color: #A7B2BE; }
.approve-input { width: 100%; margin: 0 0 18px; padding: 12px; border: 1px solid rgba(255, 255, 255, .14); border-radius: 10px; background: rgba(255, 255, 255, .045); color: #F1F4F7; font: inherit; font-size: 16px; }
.approve-input::placeholder { color: #7D8793; }
.approve-input:focus { outline: 1px solid rgba(var(--vault-light), .8); border-color: transparent; }
.approve-btns { display: flex; gap: 10px; justify-content: center; }
.approve-btns button { min-width: 110px; }
.approve-btns .ghost { color: #A7B2BE; border-color: rgba(255, 255, 255, .14); }

/* 세로 폰: 숫자판 아래 여백을 양옆 여백과 같게 해 화면 아래에 고르게 앉히고, 고리는 간격을 두고 위에 띄운다 */
@media (max-width: 480px) and (max-aspect-ratio: 3/4) {
  .vault-page {
    --pad: min(76vw, max(300px, calc(38 * var(--vh))));
    --pad-height: calc(var(--pad) * .871);    /* 단추 8:5 네 줄과 틈 */
    --msg-gap: clamp(6px, calc(calc(9.5 * var(--vh)) - 43px), 44px);   /* 주소창으로 짧아진 폰에선 간격부터 줄인다 */
    /* 로고 밑(64px)부터 숫자판 위까지 남는 높이. 고리는 이 안에 든다 */
    --ring-room: calc(100 * var(--vh) - 64px - (100vw - var(--pad)) / 2 - var(--pad-height) - 2 * var(--msg-gap) - 20px);
    justify-content: flex-end;
    padding-bottom: max(calc((100vw - var(--pad)) / 2), calc(env(safe-area-inset-bottom) + 12px));
  }
  .vault-page > .vault-msg { margin: var(--msg-gap) 0; }
  .power { width: min(68vw, calc(34 * var(--vh)), var(--ring-room)); }
  .vault-pad, .vault-gate { width: var(--pad); }
  /* 기기 승인 문구는 숫자판보다 낮아 아래에 붙이면 위가 빈다 */
  .vault-page:has(> .vault-gate:not(.hidden)) { justify-content: center; }
}
/* 키 큰 폰: 고리와 단추를 키운다 */
@media (max-width: 480px) and (max-aspect-ratio: 3/4) and (min-height: 740px) {
  .vault-page { --pad: 78vw; --pad-height: calc(var(--pad) * .923); }   /* 단추 3:2 */
  .power { width: min(72vw, calc(36 * var(--vh)), var(--ring-room)); }
  .slot { aspect-ratio: 3/2; }
}
/* 세로 태블릿·세로로 긴 창: 고리와 숫자판 간격을 바깥 여백과 비슷하게 벌린다 */
@media (min-width: 481px) and (min-height: 700px) and (max-aspect-ratio: 8/7) {
  .vault-page > .vault-msg { margin: calc(4.2 * var(--vh)) 0; }
}
/* PC 처럼 넓은 화면: 고리를 크게 하고 숫자판을 옆에 나란히 둔다 */
@media (min-width: 820px) and (min-height: 501px) and (min-aspect-ratio: 8/7) {
  .vault-screen { background: #06080b radial-gradient(44% 62% at 34% 50%, rgba(40, 92, 130, .5), rgba(12, 24, 34, .5) 58%, rgba(6, 8, 11, 0) 100%); }
  .vault-page { flex-direction: row; gap: clamp(56px, 7vw, 120px); padding-top: 20px; }
  .vault-page { --ring: min(40vw, calc(64 * var(--vh)), 560px); }
  .power { width: var(--ring); }
  /* 숫자판은 고리에 비례한다. 고정 상한을 두면 큰 모니터에서 고리만 커지고 숫자판이 작아 보인다 */
  .vault-pad, .vault-gate { width: max(300px, calc(var(--ring) * .72)); padding-top: 0; }
  .vault-screen > .vault-page > .vault-msg { position: absolute; left: 0; right: 0; bottom: 32px; margin: 0; }
}
/* 가로로 눕힌 폰: 나란히, 숫자판을 납작하게 */
@media (max-height: 500px) and (orientation: landscape) {
  .vault-page { flex-direction: row; gap: 28px; padding-top: 12px; padding-bottom: 12px; }
  .power { width: min(calc(62 * var(--vh)), 210px); }
  .vault-screen > .vault-page > .vault-msg { position: absolute; left: 0; bottom: 6px; width: 44%; margin: 0; }
  .vault-pad, .vault-gate { width: min(46vw, 300px); padding-top: 0; }
  .slot { aspect-ratio: 2/1; }
}
@media (prefers-reduced-motion: reduce) {
  .slot.hit, .slot.hit::after { animation: none; }
  .plate, .ring-fill { transition: none; }
  .device-digits.engrave b { animation: none; }
}

/* 숫자판 햅틱용 화면 밖 스위치(vault.js). display:none 이면 iOS 햅틱이 나지 않는다 */
.haptic-switch { position: fixed; left: -100px; top: 0; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
