/* SAVER 로그인 — 스마트 산소 시스템
   좌 60% 3D 산소발생기 / 우 40% 로그인. 앱 안쪽(종이·초록)과 달리
   이 화면만 화이트·딥네이비·시안으로 간다. 첫인상은 제품 브랜드다. */

:root{
  --nv:#0a1b2a;          /* 딥네이비 — 본문 */
  --nv-2:#31465a;        /* 보조 텍스트 */
  --nv-3:#7d8fa1;        /* 약한 텍스트 */
  --mist:#eef3f7;        /* 아주 연한 블루그레이 */
  --mist-2:#f7fafc;
  --line:#dde6ee;
  --cy:#0e9fb4;          /* 산소 포인트 — 남발 금지 */
  --cy-soft:rgba(14,159,180,.14);
  --red:#c0392b;
  --sans:"Pretendard","Pretendard Variable",-apple-system,system-ui,sans-serif;
  --mono:"IBM Plex Mono",ui-monospace,Menlo,monospace;
}

*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
body{font-family:var(--sans);color:var(--nv);background:#fff;
  -webkit-text-size-adjust:100%;line-height:1.55;letter-spacing:-.01em}
svg{display:block}
button{font-family:inherit}

.wrap{display:grid;grid-template-columns:minmax(0,6fr) minmax(0,4fr);min-height:100dvh}

/* ───────── 좌: 3D ───────── */
.stage{position:relative;overflow:hidden;background:
  radial-gradient(110% 80% at 32% 12%,#ffffff 0%,#eef3f8 42%,#dde7ef 78%,#d3dfe9 100%)}
#mist{position:absolute;inset:0;display:block;pointer-events:none}

/* ── 제품 ────────────────────────────────────────────
   비타에어 한 대. 빛무리·파동·부유·시차로 깊이를 만든다. */
.core{position:absolute;left:50%;top:45%;z-index:1;--px:0px;--py:0px;
  width:clamp(240px,32vw,470px);
  transform:translate(calc(-50% + var(--px)),calc(-50% + var(--py)));
  animation:dfloat 7s ease-in-out infinite}
/* 사진 한 장이라 '3D'는 결국 움직임으로 만든다.
   좌우로 천천히 도는 각(tilt) + 마우스 기울임(img) + 부유(core)를 겹친다.
   한 요소에 다 걸면 transform 이 서로를 덮어써서 층을 나눴다. */
.tilt{animation:sway 9s ease-in-out infinite;transform-origin:50% 60%}
@keyframes sway{
  0%,100%{transform:perspective(1100px) rotateY(-9deg) rotateX(1.5deg)}
  50%    {transform:perspective(1100px) rotateY(9deg)  rotateX(-1.5deg)}}
.core img{display:block;width:100%;height:auto;transform-origin:50% 60%;
  transform:perspective(1100px) rotateY(var(--ry,0deg)) rotateX(var(--rx,0deg));
  filter:drop-shadow(0 2px 3px rgba(10,27,42,.18))
         drop-shadow(0 34px 44px rgba(10,27,42,.22));
  animation:coreIn 1s cubic-bezier(.22,.9,.3,1) both}
@keyframes coreIn{from{opacity:0;filter:blur(4px)}to{opacity:1;filter:none}}
@keyframes dfloat{0%,100%{margin-top:6px}50%{margin-top:-16px}}

/* 바닥 그림자 */
.core::after{content:"";position:absolute;left:50%;bottom:-6%;width:56%;height:5%;
  border-radius:50%;background:radial-gradient(ellipse,rgba(10,27,42,.22),rgba(10,27,42,0) 70%);
  transform:translateX(-50%);animation:shadow 7s ease-in-out infinite}
@keyframes shadow{0%,100%{transform:translateX(-50%) scale(1);opacity:1}
                  50%{transform:translateX(-50%) scale(.82);opacity:.6}}
/* 뒤쪽 빛무리 — 숨 쉬듯 아주 느리게 */
.core::before{content:"";position:absolute;left:50%;top:48%;width:150%;aspect-ratio:1;
  transform:translate(-50%,-50%);border-radius:50%;z-index:-1;
  background:radial-gradient(circle,rgba(14,159,180,.20),rgba(14,159,180,0) 62%);
  animation:breathe 6s ease-in-out infinite}
@keyframes breathe{0%,100%{opacity:.75;transform:translate(-50%,-50%) scale(1)}
                   50%{opacity:1;transform:translate(-50%,-50%) scale(1.08)}}

/* 산소가 퍼져 나가는 파동 — 세 겹이 시차를 두고 번진다 */
.halo{position:absolute;left:50%;top:50%;width:74%;aspect-ratio:1;z-index:-1;
  border:1px solid rgba(14,159,180,.38);border-radius:50%;
  transform:translate(-50%,-50%) scale(.6);opacity:0;
  animation:ripple 5s cubic-bezier(.2,.6,.3,1) infinite}
.halo.h2{animation-delay:1.7s}
.halo.h3{animation-delay:3.4s}
@keyframes ripple{
  0%{transform:translate(-50%,-50%) scale(.62);opacity:0}
  12%{opacity:.5}
  100%{transform:translate(-50%,-50%) scale(1.75);opacity:0}}

/* 카피 — 3D 위에 얹되 장비를 가리지 않게 위/아래 끝으로 */
.copy{position:absolute;left:clamp(28px,5vw,64px);bottom:clamp(30px,5vh,54px);
  right:clamp(28px,5vw,64px);z-index:2;pointer-events:none}
.copy .eyebrow{font-family:var(--mono);font-size:11px;letter-spacing:.24em;
  color:var(--cy);margin-bottom:12px}
/* 로고는 문구 옆에 — 브랜드가 제품 화면 쪽에 있어야 맞다 */
.copy .line{display:flex;align-items:center;gap:clamp(16px,2.4vw,30px);flex-wrap:wrap}
.copy h1{font-size:clamp(26px,2.6vw,38px);font-weight:700;letter-spacing:-.03em;
  line-height:1.25;color:var(--nv)}
.copy .cats{margin-top:16px;padding-top:14px;border-top:1px solid var(--line);
  font-family:var(--mono);font-size:10.5px;letter-spacing:.18em;color:var(--nv-3)}

/* HUD — 장비 주변에 떠 있는 아주 작은 유리판. 장비보다 튀면 안 된다. */
.hud{position:absolute;z-index:2;pointer-events:none;
  display:grid;gap:3px;padding:9px 13px;border-radius:11px;
  background:rgba(255,255,255,.62);border:1px solid rgba(255,255,255,.9);
  box-shadow:0 6px 20px rgba(10,27,42,.07);backdrop-filter:blur(7px)}
.hud b{font-family:var(--mono);font-size:9.5px;letter-spacing:.16em;
  color:var(--nv-3);font-weight:500}
.hud i{font-style:normal;font-family:var(--mono);font-size:15px;font-weight:500;
  color:var(--nv);letter-spacing:-.02em}
.hud i em{font-style:normal;font-size:10px;color:var(--nv-3);margin-left:3px}
.hud.ok i{color:var(--cy)}
/* 살아 있다는 신호 — 초록불이 천천히 깜박인다 */
.hud .dot{display:inline-block;width:7px;height:7px;border-radius:50%;
  background:#22c55e;margin-right:7px;vertical-align:0;
  animation:blink 1.8s ease-in-out infinite}
@keyframes blink{
  0%,100%{opacity:1;box-shadow:0 0 0 0 rgba(34,197,94,.55),0 0 6px rgba(34,197,94,.9)}
  50%    {opacity:.35;box-shadow:0 0 0 5px rgba(34,197,94,0),0 0 2px rgba(34,197,94,.2)}}
.hud.ok i{color:var(--nv)}
.h-net{right:6%;top:66%}
@media(max-width:1180px){.h-net{display:none}}

/* ───────── 우: 로그인 ───────── */
.panel{display:flex;align-items:center;justify-content:center;
  padding:clamp(28px,4vw,56px);background:#fff;
  border-left:1px solid var(--line)}
.form{width:min(360px,100%)}
/* 로고 — 떠오르듯 등장한 뒤, 글자 위로 빛이 한 번씩 스쳐 지나간다.
   <img> 라 내부를 못 건드리니 로고 모양으로 마스크를 떠서 그 위에 빛을 흘린다. */
.brandwrap{position:relative;display:inline-block;
  animation:logoIn .8s cubic-bezier(.22,.9,.3,1) .55s both}
.brand{height:clamp(26px,2.3vw,34px);display:block}
@keyframes logoIn{
  from{opacity:0;transform:translateY(10px) scale(.94)}
  to{opacity:1;transform:none}}

.sheen{position:absolute;inset:0;pointer-events:none;
  -webkit-mask:url(/static/logo.svg) no-repeat left center/contain;
          mask:url(/static/logo.svg) no-repeat left center/contain;
  background:linear-gradient(105deg,
    rgba(255,255,255,0) 38%,
    rgba(255,255,255,.92) 50%,
    rgba(255,255,255,0) 62%);
  background-size:260% 100%;background-repeat:no-repeat;
  animation:sheen 5s ease-in-out 1.2s infinite}
@keyframes sheen{
  0%      {background-position:170% 0}
  38%,100%{background-position:-70% 0}}
.f{margin-top:19px}
.f:first-of-type{margin-top:0}
.f label{display:block;margin-bottom:7px;font-size:12.5px;font-weight:600;color:var(--nv)}
.f .box{position:relative}
.f input{width:100%;height:50px;padding:0 15px;font-size:15px;color:var(--nv);
  background:var(--mist-2);border:1px solid var(--line);border-radius:11px;
  transition:border-color .14s,box-shadow .14s,background .14s}
.f input::placeholder{color:#a9b7c4}
.f input:hover{background:#fff}
.f input:focus{outline:none;background:#fff;border-color:var(--cy);
  box-shadow:0 0 0 4px var(--cy-soft)}
.f input[aria-invalid="true"]{border-color:var(--red);box-shadow:0 0 0 4px rgba(192,57,43,.10)}
.f .pw input{padding-right:48px}
.f .peek{position:absolute;right:6px;top:50%;transform:translateY(-50%);
  width:38px;height:38px;display:grid;place-items:center;cursor:pointer;
  background:none;border:none;color:var(--nv-3);border-radius:9px}
.f .peek:hover{color:var(--nv);background:var(--mist)}
.f .peek svg{width:19px;height:19px;fill:none;stroke:currentColor;stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round}
.f .msg{margin-top:6px;font-size:11.5px;color:var(--red);display:none}
.f .msg.on{display:block}

.row{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:16px}
.keep{display:flex;align-items:center;gap:8px;font-size:12.5px;color:var(--nv-2);cursor:pointer}
.keep input{width:16px;height:16px;accent-color:var(--cy);cursor:pointer}
.forgot{background:none;border:none;padding:0;font-size:12.5px;color:var(--cy);cursor:pointer}
.forgot:hover{text-decoration:underline}
.hint{margin-top:9px;font-size:12px;color:var(--nv-2);background:var(--mist);
  border:1px solid var(--line);border-radius:9px;padding:9px 11px;display:none}
.hint.on{display:block}

.cta{width:100%;height:52px;margin-top:22px;border:none;border-radius:11px;cursor:pointer;
  background:var(--nv);color:#fff;font-size:15px;font-weight:600;letter-spacing:.02em;
  box-shadow:0 2px 6px rgba(10,27,42,.18);
  transition:transform .12s,box-shadow .12s,background .12s}
.cta:hover{transform:translateY(-2px);background:#0d2438;
  box-shadow:0 8px 20px rgba(10,27,42,.20),0 0 0 4px var(--cy-soft)}
.cta:active{transform:translateY(0)}

.err{margin-top:18px;font-size:12.5px;color:var(--red);
  background:#fdf0ee;border:1px solid #f2cec8;border-radius:10px;padding:10px 12px}
.foot{margin-top:26px;font-family:var(--mono);font-size:10px;letter-spacing:.14em;
  color:#a9b7c4}

/* ───────── 진입 ───────── */
@keyframes rise{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
@keyframes soft{from{opacity:0}to{opacity:1}}
.form{animation:rise .6s cubic-bezier(.22,.9,.3,1) .25s both}
.copy{animation:rise .7s cubic-bezier(.22,.9,.3,1) .5s both}
.hud{animation:soft .8s ease .8s both}

/* ───────── 모바일: 세로 ───────── */
@media(max-width:900px){
  /* 남는 높이는 로그인 쪽이 가져간다. auto auto 로 두면 3D 행이 같이 늘어나
     3D 영역(고정 높이)과 폼 사이가 통째로 빈다. */
  .wrap{grid-template-columns:1fr;grid-template-rows:auto 1fr}
  /* 키우되 상한을 둔다 — 더 키우면 로그인칸이 화면 밖으로 밀린다 */
  .stage{height:min(45dvh,360px);border-bottom:1px solid var(--line)}
  .panel{border-left:none;padding:26px 22px 40px;align-items:flex-start}
  .copy{left:20px;right:20px;bottom:16px;text-align:center}
  .copy .eyebrow{margin-bottom:6px;font-size:10px}
  .copy .line{justify-content:center;gap:12px}
  .copy h1{font-size:19px}
  .copy .cats{display:none}
  .hud{padding:7px 10px}
  .hud i{font-size:12.5px}
  .core{top:42%;width:min(60vw,250px)}
  .h-net{right:5%;top:14%}
  .brand{height:22px}
  .panel{padding-top:58px}      /* 3D 영역과 붙지 않게 한 숨 띄운다 */
  /* iOS 는 16px 미만 입력칸에 초점이 가면 화면을 확대해 버린다 */
  .f input{font-size:16px;height:52px}
}
@media(max-width:900px) and (max-height:680px){
  .stage{height:190px}
}

@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{animation:none!important;transition:none!important}
}
