:root { color-scheme: dark; }
* { box-sizing: border-box; margin: 0; padding: 0; }

/* 순수 검정 — 아트워크 가장자리 비네팅과 자연히 어우러진다. body padding 0으로 gap 없음 */
html, body { background: #000; }
html, body { height: 100%; }
body {
  font-family: -apple-system, BlinkMacSystemFont, "Apple SD Gothic Neo", "Noto Sans KR", sans-serif;
  color: #eef;
  height: 100dvh;
  overflow: hidden;                 /* 무대는 항상 화면 안 — 상하 스크롤 없음 */
  display: flex;
  align-items: center;
  justify-content: center;
}
/* 모바일: 정확히 화면 폭. 데스크톱: 세로 핏이 폭을 결정(최대 768px) — 세로 스크롤 불가조건 */
.stage { position: relative; width: 100vw; height: 100dvh; z-index: 1; }
@supports not (height: 100dvh) { .stage { height: 100vh; } }
@supports not (height: 100dvh) and (height: 100vh) { .stage { height: -webkit-fill-available; } }
@media (min-width: 769px) {
  .stage { width: min(768px, calc(100dvh * 0.5627)); height: 100dvh; }
}
.art { position: relative; z-index: 1; }
.content { z-index: 2; }
.brand { z-index: 2; }
.art {
  display: block;
  width: 100%;
  height: auto;
  transition: filter .7s ease, transform .7s ease, opacity 1s ease;
}
.art.placeholder {
  position: fixed;
  inset: 0;
  z-index: 0;
  background: radial-gradient(ellipse at 50% 30%, #1a1a2e 0%, #050508 40%, #000 75%);
}
video.art {
  position: fixed;
  inset: 0;
  z-index: 0;
  width: 100vw;
  height: 100dvh;
  height: 100svh;              /* iOS 안전 폴백 */
  object-fit: cover;
}
@supports not (height: 100svh) { video.art { height: 100vh; } }
video.art.hidden { display: none; }
/* 데스크톱: 모바일 세로영상을 화면폭으로 cover하면 상하가 잘린다 —
   아트워크와 같은 세로 컬럼(9:16)으로 제한하고 중앙 정렬 */
@media (min-width: 769px) {
  video.art, .art.placeholder {
    width: min(768px, calc(100dvh * 0.5627));
    height: 100dvh;
    left: 50%;
    transform: translateX(-50%);
  }
}
/* 첫 화면(이용권)은 선명하게, 이후 화면은 liquid glass용 블러 — scale은 블러 가장자리 은폐 */
body.beyond .art {
  filter: blur(18px) saturate(1.15) brightness(.55) contrast(1.05);
  transform: scale(1.06);
}
/* 촬영 중에는 블러 해제 — 구슬 배경이 선명해야 한다 (beyond보다 우선) */
body.capturing .art,
body.capturing video.art {
  filter: none !important;
  transform: none !important;
}

/* 브랜드(타이틀) — 포스터 상단의 어두운 구역 위 */
.brand {
  position: absolute;
  top: 7%;
  left: 0; right: 0;
  text-align: center;
  padding: 0 24px;
}
.brand h1 {
  font-size: clamp(30px, 8vw, 46px);
  font-weight: 800;
  letter-spacing: .10em;
  color: #fff;
  text-shadow: 0 1px 24px rgba(0,0,0,.85);
}
.brand .sub {
  margin-top: 10px;
  font-size: 13px;
  letter-spacing: .12em; /* 라틴 문자열 — 한글식 넓은 자간 불필요 */
  color: rgba(255,255,255,.72);
  text-shadow: 0 1px 14px rgba(0,0,0,.8);
}

/* liquid glass 패널 — 테두리 없음(inset 하이라이트로 유리 능선만).
   iOS/안드로이드 최신 질감(backdrop-filter), 이전 OS는 @supports 폴백 */
/* 콘텐츠 — 패널 없음. 요소들이 이미지 위에 직접 뜬다(가독성은 그림자로) */
.content {
  position: absolute;
  left: 20px; right: 20px;
  bottom: max(7%, env(safe-area-inset-bottom));
  text-align: center;
}
.content h2 { font-size: 21px; letter-spacing: -.01em; margin: 10px 0 6px; color:#fff;
  text-shadow: 0 1px 16px rgba(0,0,0,.85); }
.content .sub { color: rgba(238,238,255,.85); font-size: 13.5px; line-height: 1.65; margin-bottom: 14px;
  text-shadow: 0 1px 10px rgba(0,0,0,.85); }
.emoji { font-size: 34px; filter: drop-shadow(0 2px 10px rgba(0,0,0,.6)); }
.hidden { display: none !important; }

input[type=text] {
  width: 100%;
  padding: 14px;
  font-size: 18px;
  text-align: center;
  letter-spacing: .35em;
  text-indent: .35em;
  border-radius: 16px;
  border: 0;                                   /* 테두리 없음 — 유리 질감으로만 */
  background: rgba(0,0,0,.32);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.18), inset 0 0 0 1px rgba(255,255,255,.08);
  color: #fff;
  text-transform: uppercase;
}
input[type=text]:focus { outline: 2px solid rgba(255,255,255,.45); }
input[type=text]::placeholder { letter-spacing: .02em; text-indent: 0; color: rgba(255,255,255,.4); }

button {
  width: 100%;
  margin-top: 12px;
  padding: 15px;
  font-size: 16px;
  font-weight: 700;
  color: #fff;
  border: 0;
  border-radius: 16px;
  cursor: pointer;
  background: linear-gradient(180deg, rgba(255,255,255,.22), rgba(255,255,255,.10));
  -webkit-backdrop-filter: blur(14px) saturate(160%);
  backdrop-filter: blur(14px) saturate(160%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.35), 0 6px 22px rgba(0,0,0,.35);
  transition: transform .12s ease, background .2s ease;
}
button:active { transform: scale(.98); }
button:disabled { opacity: .45; cursor: default; }
/* 6자 완성 — 짙은 노랑으로 활성 신호 */
button.ready {
  background: linear-gradient(180deg, #f7c518, #dd9e00);
  color: #201600;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.5), 0 6px 26px rgba(221,158,0,.45);
}

.err { color: #ff9fb2; font-size: 13px; margin-top: 10px; min-height: 17px;
  text-shadow: 0 1px 10px rgba(0,0,0,.8); }
.steps { color: rgba(255,255,255,.5); font-size: 11px; margin-top: 14px; letter-spacing: .06em;
  text-shadow: 0 1px 10px rgba(0,0,0,.8); }

.drop {
  margin: 4px 0 6px;
  border-radius: 18px;
  padding: 26px 16px;
  cursor: pointer;
  background: rgba(0,0,0,.24);
  box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.16);
  transition: box-shadow .15s ease, background .15s ease;
}
.drop.on { box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.55); background: rgba(255,255,255,.08); }
.drop .big { font-size: 30px; }
.drop p { color: rgba(238,238,255,.72); font-size: 13px; margin-top: 8px; line-height: 1.6; }

.preview {
  width: 118px; height: 118px;
  object-fit: cover;
  border-radius: 16px;
  margin: 4px auto 2px;
  display: block;
  box-shadow: 0 8px 26px rgba(0,0,0,.5);
}

.spinner {
  width: 32px; height: 32px;
  margin: 16px auto 10px;
  border-radius: 50%;
  border: 3px solid rgba(255,255,255,.18);
  border-top-color: rgba(255,255,255,.85);
  animation: spin 1s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

#result-video {
  width: 100%;
  max-width: 300px;
  border-radius: 16px;
  margin: 10px auto 2px;
  display: block;
  box-shadow: 0 10px 30px rgba(0,0,0,.5);
}

/* 블러 화면(대기 확인 s-wait 제외한 첫 화장 외 전부)에서는 화면 중앙을 적극 사용 —
   크리스탈을 피할 필요가 없다(뿌옇게 되므로). 첫 화면만 하단 배치 유지 */
body.beyond .content {
  bottom: auto;
  top: 50%;
  transform: translateY(-50%);
}

/* 선택한 사진 썸네일 + 우상단 취소(X) — 유리 질감의 동그란 버튼 */
.preview-wrap { position: relative; width: 118px; margin: 6px auto 2px; }
.preview-wrap .preview { margin: 0; }
button.clear {
  position: absolute;
  top: -9px; right: -9px;
  width: 30px; height: 30px;
  min-width: 0;
  margin: 0;
  padding: 0;
  border-radius: 50%;
  font-size: 14px;
  line-height: 1;
  color: #fff;
  background: rgba(10,8,16,.72);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  box-shadow: 0 2px 10px rgba(0,0,0,.5), inset 0 0 0 1px rgba(255,255,255,.25);
}
button.clear:active { transform: scale(.92); }
/* 전역 상태 규약: disabled = 흐린 유리, enabled(준비완료) = 짙은 노랑 */
button:disabled { background: rgba(255,255,255,.06); }

/* 데스크톱: 버튼/입력창은 중앙 고정폭 300px — 반드시 각각 한 줄씩 */
@media (min-width: 769px) {
  .content input[type=text],
  .content button:not(.clear) {
    display: block;
    width: 300px;
    margin-left: auto;
    margin-right: auto;
  }
}

/* 버튼 내장 에러 상태 — 잘못된 이용권이 유지되는 동안 버튼 안에 메시지 */
button.error {
  background: rgba(255, 76, 98, .16);
  color: #ffb3c0;
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: 0;
}

/* ══ 촬영 — face-capture와 같은 구슬 구조 ══════════
   카메라 영상은 더 넓게 보여 주되 zoom × face-fraction을 유지해 그림의 구슬 구멍은 그대로 둔다.
   CSS 변수(--orb-*)는 #cap 요소 자체에 정의한다. */

/* HTML hidden 속성이 CSS display보다 우선 — #cap은 JS가 hidden=false할 때만 보인다 */
[hidden]{display:none!important}

#cap{--camera-zoom:1.05;--orb-face-fraction:0.30;--orb-radius:calc(100vw * var(--camera-zoom) * var(--orb-face-fraction) / 2);--orb-feather:calc(var(--orb-radius) * 0.34615);--orb-y:calc(50% - 23vw);position:fixed;inset:0;isolation:isolate;display:block;padding:0;z-index:100;}
/* stage를 부모의 정상 스택에 둔다. 음수 z-index의 video는 iOS Safari에서
   mask/clip 합성이 부모 뒤로 빠질 수 있다. 안내 UI는 z-index:2로 stage 위에 놓인다. */
#cap #cap-stage{position:absolute;inset:0;aspect-ratio:auto;border-radius:0;z-index:0;overflow:hidden;background:#000;}
#cap #cap-camera{position:absolute;inset:auto;left:50%;top:var(--orb-y);width:calc(100vw * var(--camera-zoom));height:auto;max-width:none;transform:translate(-50%,-50%) scaleX(-1);-webkit-clip-path:circle(var(--orb-radius) at 50% 50%);clip-path:circle(var(--orb-radius) at 50% 50%);z-index:0;}
#cap #cap-camera-preview{position:absolute;inset:auto;left:50%;top:var(--orb-y);width:calc(100vw * var(--camera-zoom));height:auto;max-width:none;transform:translate(-50%,-50%) scaleX(-1);z-index:0;}
/* 2026-09-17 — 이중 원형 크롭 제거(face-capture와 동일 수정): preview 캔버스의 clip-path는
   배경 마스크의 구멍과 중복이던 합성 비용일 뿐이다. 원형 절단은 녹화 crop만 담당한다. */
#cap.canvas-preview-ready #cap-camera{position:absolute;left:0;top:0;width:1px;height:1px;opacity:0;pointer-events:none;transform:none;}
#cap #cap-artwork{position:absolute;inset:0;width:100%;height:100%;max-width:none;display:block;z-index:1;object-fit:cover;transform:none;pointer-events:none;-webkit-mask-image:radial-gradient(circle at 50% var(--orb-y),transparent calc(var(--orb-radius) - var(--orb-feather)),#000 var(--orb-radius));mask-image:radial-gradient(circle at 50% var(--orb-y),transparent calc(var(--orb-radius) - var(--orb-feather)),#000 var(--orb-radius));}
#cap #cap-oval{top:var(--orb-y);left:50%;transform:translate(-50%,-50%);width:calc(var(--orb-radius) * 2);height:calc(var(--orb-radius) * 2);position:absolute;border:0;border-radius:50%;box-shadow:none;pointer-events:none;}
#cap #cap-angle{position:absolute;z-index:2;top:calc(var(--orb-y) + var(--orb-radius) + 16px);left:50%;transform:translateX(-50%);background:#14251bd9;padding:7px 13px;white-space:nowrap;border-radius:20px;font-size:12px;}
#cap > :not(#cap-stage){position:absolute;z-index:2;}
/* 안내문 — 화면 상단(구슬 중심 기준 대칭)에 위치.
   구슬 중심(--orb-y)에서 메시지까지 거리 = 구슬 중심에서 앨범 버튼까지 거리 */
#cap #cap-instruction{
  top:7%;left:0;right:0;text-align:center;
  font-size:20px;color:#fff;text-shadow:0 1px 5px #000;margin:0;
}
#cap #cap-instruction.pitchWarning{color:#ff6868;}
#cap #cap-instruction.measurementLoading{display:flex;align-items:center;justify-content:center;min-height:28px;}
#cap #cap-instruction.measurementLoading::before{content:"";display:block;width:22px;height:22px;border:2px solid #ffffff45;border-top-color:#fff;border-radius:50%;animation:measurement-spin .8s linear infinite;}
@keyframes measurement-spin{to{transform:rotate(360deg)}}

/* 각도 표시 — 구슬 아래 (기존 위치 유지) */
#cap #cap-angle{
  position:absolute;z-index:2;
  top:calc(var(--orb-y) + var(--orb-radius) + 16px);
  left:50%;transform:translateX(-50%);
  background:#14251bd9;padding:7px 13px;white-space:nowrap;
  border-radius:20px;font-size:12px;
}

/* 앨범에서 선택 — 구슬 중심 대칭 하단.
   top = 2×(50% - 23vw) - 7% = 93% - 46vw (메시지 top 7%의 거울 대칭) */
#cap #btn-album{
  -webkit-appearance:none;appearance:none;
  background:none;border:none;outline:none;box-shadow:none;border-radius:0;
  width:auto;min-height:0;padding:8px 16px;margin:0;
  color:rgba(238,238,255,.35);font-size:13px;font-weight:400;
  cursor:pointer;-webkit-tap-highlight-color:transparent;
  text-decoration:none;display:inline;
  position:absolute;
  top:calc(93% - 46vw);left:50%;transform:translateX(-50%);
  text-align:center;
}

/* 가로 모드 오버레이 */
#cap-rotate{display:none;position:fixed;inset:0;z-index:8;background:rgba(10,10,18,.95);font-size:21px;line-height:1.5;padding:24px;text-align:center;color:#fff;}
#cap-rotate small{display:block;margin-top:10px;font-size:13px;color:#aebbb7;}
@media (orientation:landscape){
  body.capturing #cap-rotate{display:flex;flex-direction:column;align-items:center;justify-content:center;}
  #cap > :not(#cap-stage):not(#cap-rotate){visibility:hidden;}
}

/* 촬영 중 기존 페이지 숨김 */
body.capturing{overflow:hidden;}
body.capturing .stage{display:none;}
body.capturing .brand{display:none;}
body.capturing #bg-video{display:none;}
body.capturing #art-placeholder{display:none;}

/* 권한 허용 화면 */
#s-permission h2{margin:10px 0 8px;}
.cap-btn{
  display:inline-block;min-height:52px;min-width:200px;margin:16px 0 6px;
  padding:14px 30px;border:0;border-radius:26px;font-size:16px;font-weight:650;
  background:linear-gradient(135deg,#7c6cf0,#5a4ae0);color:#fff;cursor:pointer;
}

/* 더블 터치 줌 방지 */
html{touch-action:manipulation;}

/* ── 데스크톱 업로드(2026-09-19) — 카메라 없이 사진 업로드+드래그앤드롭 ── */
#s-desktop h2{margin:10px 0 8px;}
#s-desktop .fine{color:rgba(238,238,255,.5);font-size:12px;margin-top:10px;}
.dropzone{
  display:flex;flex-direction:column;align-items:center;gap:4px;
  margin:18px 0 4px;padding:34px 28px;border-radius:18px;
  border:1.5px dashed rgba(238,238,255,.28);
  background:rgba(238,238,255,.03);transition:border-color .15s,background .15s;
}
.dropzone.dragging{
  border-color:#7c6cf0;background:rgba(124,108,240,.10);
}
.dropzone .sub{margin-bottom:4px;}
/* 데스크톱에서는 카메라 진입점(s-permission)을 숨긴다 — JS 분기와 이중 방어. */
@media (hover: hover) and (pointer: fine) {
  body.desktop-hide-camera #s-permission{display:none;}
}
