/* 연출: 배경 움직임과 스크롤 연동 효과
   전부 prefers-reduced-motion 을 따른다. 꺼져도 내용은 그대로 읽힌다. */

/* ══ 배경: 흐르는 빛무리 ═══════════════════════════════
   덩어리 세 개가 서로 다른 주기로 천천히 떠다닌다.
   blur 를 크게 줘서 경계가 보이지 않게 한다. */
.bg-aurora{position:absolute;inset:0;overflow:hidden;pointer-events:none;z-index:0}
/* 흐림 필터(blur 88px) 대신 같은 번짐을 그라데이션으로 그린다. 큰 면에 흐림을 걸면 움직일 때마다 다시 흐려야 해서 휴대폰에서 무겁다.
   --aurora-c 는 덩어리 색. scale 1.4 로 흐림이 번지던 크기를 맞춘다. 화면 밖이면 fx.js 가 [data-fx-idle] 을 붙여 멈춘다. */
.bg-aurora__blob{position:absolute;border-radius:50%;opacity:.55;scale:1.4;
  background:radial-gradient(closest-side,color-mix(in srgb,var(--aurora-c) 63%,transparent),color-mix(in srgb,var(--aurora-c) 45%,transparent) 36%,
    color-mix(in srgb,var(--aurora-c) 25%,transparent) 55%,color-mix(in srgb,var(--aurora-c) 12%,transparent) 71%,color-mix(in srgb,var(--aurora-c) 4%,transparent) 85%,transparent)}
.bg-aurora[data-fx-idle] .bg-aurora__blob{animation-play-state:paused}
.bg-aurora__blob:nth-child(1){width:46vw;height:46vw;min-width:380px;min-height:380px;
  top:-14%;right:-8%;--aurora-c:var(--glow-accent);
  animation:drift-a 26s var(--ease-inout) infinite alternate}
.bg-aurora__blob:nth-child(2){width:38vw;height:38vw;min-width:300px;min-height:300px;
  bottom:-18%;left:-10%;--aurora-c:var(--glow-violet);
  animation:drift-b 32s var(--ease-inout) infinite alternate}
.bg-aurora__blob:nth-child(3){width:30vw;height:30vw;min-width:240px;min-height:240px;
  top:34%;left:38%;--aurora-c:var(--glow-mint);
  animation:drift-c 38s var(--ease-inout) infinite alternate;opacity:.4}
@keyframes drift-a{from{transform:translate3d(0,0,0) scale(1)}
  to{transform:translate3d(-8%,10%,0) scale(1.14)}}
@keyframes drift-b{from{transform:translate3d(0,0,0) scale(1)}
  to{transform:translate3d(12%,-8%,0) scale(1.1)}}
@keyframes drift-c{from{transform:translate3d(0,0,0) scale(.94)}
  to{transform:translate3d(-14%,-12%,0) scale(1.18)}}
[data-theme="dark"] .bg-aurora__blob{opacity:.2}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .bg-aurora__blob{opacity:.2}}

/* ══ 배경: 결 ═════════════════════════════════════════
   아주 옅은 잡티를 얹어 그라데이션의 띠(banding)를 지운다. */
.bg-grain{position:absolute;inset:0;pointer-events:none;z-index:1;opacity:.025;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E")}

/* ══ 배경: 흐르는 점 격자 ══════════════════════════════ */
.bg-dots{position:absolute;inset:0;pointer-events:none;z-index:0;
  background-image:radial-gradient(var(--line-strong) 1px,transparent 1px);
  background-size:24px 24px;opacity:.5;
  -webkit-mask-image:radial-gradient(ellipse 76% 58% at 50% 0%,#000 12%,transparent 78%);
  mask-image:radial-gradient(ellipse 76% 58% at 50% 0%,#000 12%,transparent 78%);
  animation:dots-pan 44s linear infinite}
@keyframes dots-pan{from{background-position:0 0}to{background-position:240px 240px}}

/* ══ 배경: 도는 후광 ══════════════════════════════════ */
.bg-halo{position:absolute;inset:-40%;pointer-events:none;z-index:0;border-radius:50%;
  background:conic-gradient(from 0deg,transparent 0deg,var(--halo-accent) 70deg,
    transparent 150deg,var(--halo-violet) 230deg,transparent 320deg);
  filter:blur(70px);opacity:.5;animation:halo-spin 40s linear infinite}
@keyframes halo-spin{to{transform:rotate(1turn)}}
[data-theme="dark"] .bg-halo{opacity:.16}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .bg-halo{opacity:.16}}

/* ══ 글자: 한 덩어리씩 켜지기 ══════════════════════════
   스크롤 진행도에 맞춰 단어가 차례로 진해진다. JS 가 --lit 을 올린다. */
.lit{--lit:0}
.lit__w{display:inline-block;color:var(--ink-disabled);
  transition:color var(--d-3) var(--ease-inout)}
.lit__w[data-on]{color:var(--ink)}
.lit--muted .lit__w[data-on]{color:var(--ink-body)}

/* ══ 붙어서 바뀌는 장면 ════════════════════════════════
   설명이 넘어갈 때마다 화면이 바뀐다.
   1000px 이상: 왼쪽 설명, 오른쪽에 붙은 화면.
   1000px 미만: 화면이 위에 붙어 있고, 설명 카드가 그 위로 차례로 지나간다.
   .scene__shot 에 data-steps="2-4" 를 주면 여러 단계 동안 같은 화면을 둔다.
   화면 안 요소에 data-scene-from="3" 을 주면 3단계부터 나타난다(대화가 한 줄씩 쌓이는 장면). data-scene-to="3" 은 3단계까지만 보인다(창이 닫히는 장면). */
/* --fx-vh: fx.js 가 처음 잰 화면 높이(px). 도구막대가 나타나고 사라져도 바뀌지 않는다. JS 가 없으면 작은 화면 높이. */
:root{--fx-vh:100vh}
@supports (height:100svh){:root{--fx-vh:100svh}}
.scene{position:relative;--scene-stage-h:min(calc(var(--fx-vh) * .64),560px)}
.scene__grid{display:grid;grid-template-columns:minmax(0,1fr)}
.scene__steps{display:flex;flex-direction:column;position:relative;z-index:1;
  padding-top:calc(var(--scene-stage-h) + 56px);padding-bottom:calc(var(--fx-vh) * .18);gap:calc(var(--fx-vh) * .52)}
.scene__step{position:relative;padding:20px 20px 22px;border-radius:var(--r-2xl);
  background:color-mix(in srgb,var(--surface) 88%,transparent);
  -webkit-backdrop-filter:saturate(160%) blur(18px);backdrop-filter:saturate(160%) blur(18px);
  box-shadow:var(--sh-lg),inset 0 0 0 1px var(--line);
  transition:transform var(--d-5) var(--ease-out),box-shadow var(--d-4) var(--ease-inout)}
.fx-js .scene__step:not([data-on]){transform:scale(.97)}
.scene__stage{grid-area:1/1;align-self:start;position:sticky;z-index:0;overflow-anchor:none;
  top:calc(var(--nav-h) + 16px);display:grid;place-items:center}
.scene__steps{grid-area:1/1}
.scene__frame{position:relative;height:var(--scene-stage-h);aspect-ratio:9/19.5;max-width:100%}
.scene__frame .phone{width:100%;height:100%}
.scene__shot{position:absolute;inset:0;display:grid;place-items:center;
  opacity:0;transform:translate3d(0,18px,0) scale(.965);
  transition:opacity var(--d-4) var(--ease-out),transform var(--d-5) var(--ease-out);
  pointer-events:none}
.scene__shot[data-on]{opacity:1;transform:none;pointer-events:auto}
.fx-js .scene :is([data-scene-from],[data-scene-to]):not([data-shown]){display:none}
.fx-js .scene [data-scene-from][data-shown]{animation:scene-pop var(--d-5) var(--ease-out) both}
@keyframes scene-pop{from{opacity:0;transform:translate3d(0,14px,0) scale(.97)}to{opacity:1;transform:none}}
@media (min-width:1000px){
  .scene{--scene-stage-h:min(calc(var(--fx-vh) - var(--nav-h) - 96px),640px)}
  .scene__grid{grid-template-columns:minmax(0,1fr) minmax(0,440px);column-gap:72px;align-items:start}
  .scene__steps{grid-area:auto;padding:0;gap:0}
  .scene__step{padding:calc(var(--fx-vh) * .14) 0;border-radius:0;background:none;box-shadow:none;
    -webkit-backdrop-filter:none;backdrop-filter:none;opacity:.32;
    transition:opacity var(--d-4) var(--ease-inout)}
  .fx-js .scene__step:not([data-on]){transform:none}
  .scene__step[data-on]{opacity:1}
  .scene__stage{grid-area:auto;top:calc(var(--nav-h) + 48px)}
}

/* ══ 숫자 세기 ════════════════════════════════════════ */
.count{font-variant-numeric:tabular-nums}

/* ══ 시차·진행도에 물린 변형 ═══════════════════════════
   합성 레이어(will-change)는 화면 가까이 온 동안만 연다(fx.js 가 data-fx-near). 늘 열어 두면 요소 수만큼 메모리를 쓴다. */
[data-parallax][data-fx-near]{will-change:transform}
[data-scrub][data-fx-near]{will-change:transform,opacity}
/* 스크럽 rise 는 첫 그리기부터 시작 상태로 둔다(fx.js 가 늦게 떠도 한 번 보였다가 사라지지 않게). */
.fx-js [data-scrub="rise"]:not([data-fx-ready]){opacity:0;transform:translate3d(0,40px,0)}
.fx-js [data-scrub="clip"]:not([data-fx-ready]){clip-path:inset(10% 7% round 48px)}

/* ══ 가로로 흐르는 띠 ══════════════════════════════════
   768px 이상: 세로 스크롤이 가로 이동을 민다. 구역 높이(--hscroll-h)만큼 움직인다.
   768px 미만: 손가락으로 넘기는 스냅 띠. 아래에 진행 점이 붙는다. */
.hscroll{position:relative}
.hscroll__pin{position:relative;container-type:inline-size}
.hscroll__track{display:flex;gap:16px;padding-inline:20px;overflow-x:auto;scroll-snap-type:x mandatory;
  scroll-padding-inline:20px;scrollbar-width:none;padding-block:4px 8px}
.hscroll__track::-webkit-scrollbar{display:none}
.hscroll__card{flex:none;width:min(78vw,340px);scroll-snap-align:center}
@media (min-width:768px){
  .hscroll{height:var(--hscroll-h,calc(var(--fx-vh) * 2.4))}
  .hscroll__pin{position:sticky;top:0;height:var(--fx-vh);display:flex;align-items:center;overflow:hidden}
  .hscroll__track{gap:20px;padding-inline:max(32px,calc((100cqw - var(--w-wide) - 80px) / 2 + 32px));overflow:visible;scroll-snap-type:none}
  .hscroll__track[data-fx-near]{will-change:transform}
  .hscroll__card{width:min(72vw,340px)}
}
@media (min-width:1280px){.hscroll__track{padding-inline:max(40px,calc((100cqw - var(--w-wide) - 80px) / 2 + 40px))}}

/* ══ 진행 점 ══════════════════════════════════════════
   가로 스냅 띠 바로 뒤에 JS 가 붙인다. 점 버튼은 32×44, 보이는 점은 ::after. */
.snapdots{display:flex;justify-content:center;gap:0;margin-top:8px}
.snapdots[hidden]{display:none}
.snapdots__dot{position:relative;width:24px;height:44px;border:0;background:none;padding:0;cursor:pointer}
.snapdots__dot::after{content:"";position:absolute;top:50%;left:50%;width:6px;height:6px;border-radius:var(--r-full);
  translate:-50% -50%;background:var(--line-strong);
  transition:width var(--d-3) var(--ease-out),background-color var(--d-2) var(--ease-inout)}
.snapdots__dot[aria-current]::after{width:20px;background:var(--accent)}
@media (min-width:768px){.snapdots--narrow{display:none}}

/* ══ 쌓이는 카드 ══════════════════════════════════════
   스크롤하면 카드가 위로 겹쳐 쌓인다. 다음 카드가 덮는 만큼 뒤 카드가 작아지고 어두워진다.
   화면보다 긴 카드는 붙지 않는다(JS 가 data-stack-static). 카드 배경은 불투명해야 한다. */
.stackcards{display:flex;flex-direction:column;gap:20px}
.stackcards__item{position:sticky;top:calc(var(--nav-h) + 12px + var(--stack-i,0) * 10px);
  transform-origin:center top;transform:scale(calc(1 - var(--stack-p,0) * .06));isolation:isolate}
.stackcards__item::before{content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;z-index:5;
  background:var(--scrim);opacity:calc(var(--stack-p,0) * .22)}
.stackcards__item[data-stack-static]{position:relative;top:auto}
@media (min-width:768px){
  .stackcards{gap:24px}
  .stackcards__item{top:calc(var(--nav-h) + 24px + var(--stack-i,0) * 14px)}
}

/* ══ 마우스를 따라오는 빛 ══════════════════════════════ */
.spotlight{position:relative;overflow:hidden;isolation:isolate}
.spotlight::before{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:radial-gradient(320px circle at var(--mx,50%) var(--my,50%),
    var(--accent-soft),transparent 70%);
  opacity:0;transition:opacity var(--d-3) var(--ease-inout)}
@media (hover:hover){.spotlight:hover::before{opacity:1}}

/* ══ 올렸을 때 기울기 ══════════════════════════════════ */
/* 따라가는 동안은 짧게(fx.js 가 data-tilting), 벗어나면 원래 자리로 천천히 */
[data-tilt]{transition:transform var(--d-4) var(--ease-out);transform-style:preserve-3d}
[data-tilt][data-tilting]{transition-duration:80ms;transition-timing-function:linear;will-change:transform}

/* ══ 흐르는 띠(로고·문구) ══════════════════════════════ */
.ticker{overflow:hidden;-webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent)}
.ticker__track{display:flex;gap:48px;width:max-content;animation:ticker 32s linear infinite}
@media (hover:hover){.ticker:hover .ticker__track{animation-play-state:paused}}
.ticker:focus-within .ticker__track{animation-play-state:paused}
@keyframes ticker{to{transform:translateX(-50%)}}

/* ══ 모션 축소 ════════════════════════════════════════ */
@media (prefers-reduced-motion:reduce){
  .bg-aurora__blob,.bg-dots,.bg-halo,.ticker__track{animation:none !important}
  .lit__w{color:var(--ink) !important}
  .scene__step{transform:none !important}
  .scene__shot{transform:none !important}
  .scene [data-scene-from]{animation:none !important}
  .hscroll{height:auto !important}
  .hscroll__pin{position:static;height:auto}
  .hscroll__track{transform:none !important;overflow-x:auto}
  .stackcards__item{position:relative;top:auto;transform:none !important}
  .stackcards__item::before{opacity:0 !important}
  [data-parallax],[data-scrub]{transform:none !important;clip-path:none !important;opacity:1 !important}
  [data-tilt]{transform:none !important}
  .snapdots__dot::after{transition:none}
}

/* 모바일 스크롤 장면: 설명이 폰을 덮지 않도록 아래 고정 캡션으로 바꾼다.
   원래 설명은 문서 순서에 남아 스크린리더에서 모든 단계를 읽을 수 있다.
   html.fx-js: 마케팅 레이아웃 머리말(또는 fx.js)이 붙인다. 첫 그리기부터 이 배치를 써서 fx.js 가 늦게 떠도 문서 길이가 바뀌지 않는다.
   캡션(.scene__caption, .scene__shot-caption)은 서버가 첫 단계 내용으로 미리 그린다. */
.scene__caption{display:none}
@media (max-width:999px){
 .fx-js .scene{--scene-design-h:600px;--scene-reserve:var(--s-200);
   --scene-stage-h:min(calc(var(--fx-vh) - var(--nav-h) - var(--scene-reserve)),var(--scene-design-h))}
 .fx-js .scene__steps{padding:0;gap:0;pointer-events:none}
 .fx-js .scene__step{min-height:calc(var(--fx-vh) * .78);height:calc(var(--fx-vh) * .78);padding:0;opacity:0;box-shadow:none;background:none;backdrop-filter:none;-webkit-backdrop-filter:none;transform:none}
 .fx-js .scene__step:last-child{min-height:max(var(--fx-vh),calc(var(--scene-stage-h) + var(--s-240)));height:max(var(--fx-vh),calc(var(--scene-stage-h) + var(--s-240)))}
 /* 첫 단계는 폰이 붙기 전 들어오는 구간을 빼면 머무는 거리가 짧다. 다른 단계만큼 캡션이 보이도록 길게 둔다. */
 .fx-js .scene__step:first-child{min-height:calc(var(--fx-vh) * 1.3);height:calc(var(--fx-vh) * 1.3)}
 .fx-js .scene__stage{display:flex;flex-direction:column;align-items:center;gap:var(--s-16);top:calc(var(--nav-h) + var(--s-16));padding-bottom:var(--s-16)}
 .fx-js .scene__frame{flex-shrink:0}
 /* 도구막대가 숨은 채 열었다가 나타난 경우처럼 화면이 처음보다 작아지면 폰만 줄여 캡션이 가려지지 않게 한다.
    붙어 있는 무대 안의 크기라 문서 길이는 바뀌지 않는다. 처음 연 화면보다 커질 때는 그대로다. */
 @supports (height:100dvh){.fx-js .scene__frame{height:min(var(--scene-stage-h),calc(100dvh - var(--nav-h) - var(--scene-reserve)))}}
 /* 폰 목업은 디자인 크기(--scene-design-h)로 그리고 비율만 줄인다. 작은 화면에서도 목업 속 글자가 다시 줄바꿈되지 않는다.
    --scene-k(무대 높이 / 디자인 높이)는 fx.js 가 잰다. */
 .fx-js .scene__shot{place-items:start}
 .fx-js .scene__frame .phone{flex:none;width:calc(var(--scene-design-h) * 9 / 19.5);height:var(--scene-design-h);
   transform:scale(var(--scene-k,1));transform-origin:0 0}
 .fx-js .scene__caption{display:block;width:100%;text-align:center;max-width:var(--w-sm)}
 .scene__caption :is(.step-no,.mk-step-no){display:inline-flex}
 .scene__caption :is(h2,h3){font-size:var(--t-heading-md);line-height:var(--t-heading-md-lh);letter-spacing:var(--t-heading-md-ls)}
 .scene__caption p{font-size:var(--t-body-sm);line-height:var(--t-body-sm-lh);margin-inline:auto}
 /* 세로가 짧은 폰(처음 잰 높이 740px 미만): 캡션을 줄여 폰 자리를 넓힌다. */
 .fx-js[data-fx-compact] .scene{--scene-reserve:calc(var(--s-160) + var(--s-16))}
 .fx-js[data-fx-compact] .scene__stage{gap:var(--s-12)}
 .fx-js[data-fx-compact] .scene__caption :is(h2,h3){font-size:var(--t-heading-sm);line-height:var(--t-heading-sm-lh);letter-spacing:var(--t-heading-sm-ls)}
 .fx-js[data-fx-compact] .scene__caption p{font-size:var(--t-caption);line-height:var(--t-caption-lh)}
}
.scene__shot-caption{display:none}
/* 아주 낮은 화면(처음 잰 높이 600px 미만, 가로 모드 등): 작은 폰으로 압축하지 않고 각 장면을 차례로 보여 준다.
   기준은 미디어 쿼리가 아니라 처음 잰 높이(html[data-fx-short])다. 미디어 쿼리로 두면 주소창·인앱 도구막대가
   나타나고 사라질 때마다 두 배치가 번갈아 바뀌어 페이지가 튄다. */
@media (max-width:999px){
 .fx-js[data-fx-short] .scene__grid{display:block}
 .fx-js[data-fx-short] .scene__steps{position:absolute;width:var(--s-2);height:var(--s-2);overflow:hidden;clip-path:inset(50%);padding:0}
 .fx-js[data-fx-short] .scene__stage{position:static;padding:0}
 .fx-js[data-fx-short] .scene__frame{height:auto;aspect-ratio:auto;width:100%;display:flex;flex-direction:column;gap:var(--s-64)}
 .fx-js[data-fx-short] .scene__shot{position:relative;inset:auto;opacity:1;transform:none;transition:none;gap:var(--s-20);place-items:center}
 .fx-js[data-fx-short] .scene__frame .phone{width:min(calc(100vw - var(--s-64)),calc(var(--s-240) + var(--s-40)));height:auto;transform:none}
 .fx-js[data-fx-short] .scene__caption{display:none}
 .fx-js[data-fx-short] .scene__shot-caption{display:block;text-align:center;max-width:var(--w-sm)}
 .fx-js[data-fx-short] .scene__shot-caption :is(h2,h3){font-size:var(--t-heading-md);line-height:var(--t-heading-md-lh);letter-spacing:var(--t-heading-md-ls)}
 .fx-js[data-fx-short] .scene__shot-caption p{font-size:var(--t-body-sm);line-height:var(--t-body-sm-lh);margin-inline:auto}
}
/* JS가 없어도 첫 앱 화면과 모든 설명을 겹침 없이 읽을 수 있다. */
html:not(.fx-js) .scene__grid{display:flex;flex-direction:column;gap:var(--s-40)}
html:not(.fx-js) .scene__steps{padding:0;gap:var(--s-16)}
html:not(.fx-js) .scene__step{padding:var(--s-24);opacity:1;transform:none}
html:not(.fx-js) .scene__stage{position:static;order:-1}
html:not(.fx-js) .scene__frame{width:calc(var(--s-240) + var(--s-40));height:auto}

/* ══ 데스크톱 장면(.scene--desktop) ═══════════════════
   폰 대신 브라우저 창(.browser) 하나가 붙어 있고, 단계마다 창 안 화면(.scene__shot)과 주소창 글자(화면의 data-url)가 바뀐다.
   .scene__frame 은 창의 .browser__screen 이다. 화면 안 목업은 .browser__canvas(설계 폭 1280)로 그려 비율만 줄인다(modules.css).
     .scene.scene--desktop > .scene__grid > (.scene__steps > .scene__step…) + (.scene__stage > .browser > .browser__bar + .browser__screen.scene__frame > .scene__shot[data-url]…)
   1000px 이상: 왼쪽 설명(좁은 열) · 오른쪽 넓은 창. 창은 남은 높이의 가운데에 붙는다(fx.js 가 창 높이를 --scene-browser-h 로 잰다).
   1000px 미만: 창이 위에 붙고 그 아래 캡션이 단계를 따라 바뀐다(폰 장면과 같은 규칙). 창 화면은 정사각형으로 두고 화면마다 --focus-x 쪽을 보여 준다.
   모션 축소(모든 폭) · 낮은 화면(처음 잰 높이 600px 미만, 999px 이하): 붙이지 않고 화면과 설명을 차례로 나열한다(화면마다 둥근 판 + 설명).
   --scene-top: 붙는 위치의 기준(기본 --nav-h). 내비 밑에 붙는 띠가 더 있는 페이지는 그 높이를 더해 준다. */
.scene--desktop{--scene-top:var(--nav-h)}
.scene--desktop .scene__stage{display:block}
.scene--desktop .scene__stage > .browser{margin-inline:auto}
.scene--desktop .scene__frame{height:auto;aspect-ratio:var(--browser-ratio);max-width:none}
/* 화면이 바뀔 때 창은 그대로 두고 안쪽만 살짝 가라앉으며 바뀐다(폰 장면처럼 아래서 올라오면 창 안에서 내용이 튄다) */
.scene--desktop .scene__shot{display:block;transform:scale(1.012)}
.scene--desktop .scene__shot[data-on]{transform:none}
@media (min-width:1000px){
  .scene--desktop{--scene-stage-h:min(calc(var(--fx-vh) - var(--scene-top) - var(--s-96)),760px)}
  .scene--desktop .scene__grid{grid-template-columns:minmax(0,1fr) minmax(0,1.85fr);column-gap:var(--s-56)}
  .scene--desktop .scene__stage{top:calc(var(--scene-top) + max(var(--s-24),(var(--fx-vh) - var(--scene-top) - var(--scene-browser-h,480px)) / 2))}
  .scene--desktop .scene__stage > .browser{max-width:min(var(--browser-w),calc((var(--scene-stage-h) - var(--browser-bar-h)) * (var(--browser-ratio))))}
  /* 마지막 단계가 활성선(화면 55%)을 지난 뒤에도 창이 잠깐 더 붙어 있게 */
  .scene--desktop .scene__step:last-child{min-height:calc(var(--fx-vh) * .6)}
}
/* 좁은 화면: 창 화면을 정사각형으로 두고 목업을 화면 높이에 맞춰 키운다(설계 높이 800 이 화면 높이). 가로는 화면마다 보여 줄 곳(--focus-x, 0~1,
   기본 .5)을 가운데로 두고 양 끝을 넘지 않게 자른다. 폭에 맞춰 통째로 줄이면 1280 화면이 4분의 1 크기가 되어 글자를 읽을 수 없다. */
@media (max-width:999px) and (prefers-reduced-motion:no-preference){
  .fx-js:not([data-fx-short]) .scene--desktop .scene__stage{display:flex;top:calc(var(--scene-top) + var(--s-16))}
  .fx-js:not([data-fx-short]) .scene--desktop .scene__frame{height:auto;aspect-ratio:1}
  .fx-js:not([data-fx-short]) .scene--desktop .scene__stage > .browser{flex:none;
    max-width:min(var(--browser-w),calc(var(--fx-vh) - var(--scene-top) - var(--scene-reserve) - var(--browser-bar-h)))}
  .fx-js:not([data-fx-short]) .scene--desktop .scene__shot > .browser__canvas{
    transform:translate(clamp(calc((1 - var(--browser-ratio)) * 100cqw),calc((.5 - var(--browser-ratio) * var(--focus-x,.5)) * 100cqw),0px),0)
      scale(calc(var(--browser-k) * var(--browser-ratio)))}
}
html:not(.fx-js) .scene--desktop .scene__frame{width:auto}
/* 나열(모션 축소): 설명은 화면 읽기용으로 남기고, 화면마다 둥근 판과 그 화면의 설명(.scene__shot-caption)을 차례로 둔다 */
@media (prefers-reduced-motion:reduce){
  .scene--desktop .scene__grid{display:block}
  .scene--desktop .scene__steps{position:absolute;width:var(--s-2);height:var(--s-2);overflow:hidden;clip-path:inset(50%);padding:0}
  .scene--desktop .scene__stage{position:static;display:block;padding:0}
  .scene--desktop .scene__stage > .browser{max-width:var(--browser-w);background:none;box-shadow:none;border-radius:0;overflow:visible}
  .scene--desktop .scene__stage > .browser > :is(.browser__bar,.browser__tabs){display:none}
  .scene--desktop .scene__frame{aspect-ratio:auto;overflow:visible;-webkit-mask-image:none;background:none;container-type:normal;display:flex;flex-direction:column;gap:var(--s-56)}
  .scene--desktop .scene__shot{position:relative;inset:auto;display:flex;flex-direction:column;align-items:stretch;gap:var(--s-20);opacity:1;transform:none;transition:none;pointer-events:auto;container-type:inline-size}
  .scene--desktop .scene__shot::before{content:"";display:block;aspect-ratio:var(--browser-ratio);border-radius:var(--r-lg);background:var(--canvas);box-shadow:0 0 0 1px var(--line),var(--sh-lg)}
  .scene--desktop .scene__shot > .browser__canvas{border-radius:calc(var(--r-lg) / var(--browser-k))}
  .scene--desktop .scene__caption{display:none}
  .scene--desktop .scene__shot-caption{display:block;width:100%;max-width:var(--w-sm);margin-inline:auto;text-align:center}
}
/* 나열(낮은 좁은 화면): 위와 같은 모양 */
@media (max-width:999px){
  .fx-js[data-fx-short] .scene--desktop .scene__stage{display:block}
  .fx-js[data-fx-short] .scene--desktop .scene__stage > .browser{max-width:var(--browser-w);background:none;box-shadow:none;border-radius:0;overflow:visible}
  .fx-js[data-fx-short] .scene--desktop .scene__stage > .browser > :is(.browser__bar,.browser__tabs){display:none}
  .fx-js[data-fx-short] .scene--desktop .scene__frame{aspect-ratio:auto;overflow:visible;-webkit-mask-image:none;background:none;container-type:normal;gap:var(--s-56)}
  .fx-js[data-fx-short] .scene--desktop .scene__shot{display:flex;flex-direction:column;align-items:stretch;container-type:inline-size}
  .fx-js[data-fx-short] .scene--desktop .scene__shot::before{content:"";display:block;aspect-ratio:var(--browser-ratio);border-radius:var(--r-lg);background:var(--canvas);box-shadow:0 0 0 1px var(--line),var(--sh-lg)}
  .fx-js[data-fx-short] .scene--desktop .scene__shot > .browser__canvas{border-radius:calc(var(--r-lg) / var(--browser-k))}
}
