/* === 시작하기 테마 강제 === */

:root{--bg:#0B1020;--surface:#141B2F;--navy:#1E3A6E;--purple:#6B5CE6;--text:#E8ECF4;--muted:#8B95A8;--line:rgba(255,255,255,.08)}
*{box-sizing:border-box}
html,body{margin:0;background:var(--bg)!important;color:var(--text)!important;font-family:"Pretendard Variable",Pretendard,"Noto Sans KR",sans-serif;line-height:1.65}
.wrap{max-width:920px;margin:0 auto;padding:48px 20px 80px}
.eyebrow,.theme-eyebrow{color:var(--purple)!important;font-weight:800;letter-spacing:.12em;font-size:.75rem;text-transform:uppercase;margin:0 0 10px}
h1{font-size:clamp(1.8rem,4vw,2.4rem);letter-spacing:-.03em;margin:0 0 8px;color:var(--text)!important}
.lede{color:var(--muted)!important;margin:0 0 28px}
.grid,.grid.cards,.launcher-grid{display:grid;gap:12px}
a.card{display:block!important;text-decoration:none!important;color:inherit!important;background:var(--surface)!important;border:1px solid var(--line)!important;border-radius:14px!important;padding:18px 20px!important;transition:.15s;min-height:auto}
a.card:hover{border-color:rgba(107,92,230,.45)!important}
a.card b{display:block;font-size:1.05rem;margin-bottom:4px;color:var(--text)!important}
a.card span{color:var(--muted)!important;font-size:.9rem;display:block}
a.card.primary{border-color:rgba(107,92,230,.55)!important;background:linear-gradient(135deg,rgba(30,58,110,.55),rgba(107,92,230,.25))!important}
.note{margin-top:28px;font-size:.85rem;color:var(--muted)!important}
/* force dark on common chrome */
.site-header{background:rgba(11,16,32,.92)!important;border-bottom:1px solid var(--line)!important}
.site-nav a{color:var(--muted)!important}
.footer{background:#0B1020!important;color:var(--muted)!important}
.section-white,.product-card,.tech-card,.contact-form,.distinction,.news-card{background:var(--surface)!important;color:var(--text)!important;border-color:var(--line)!important}


:root {
  --bg: #0B1020;
  --surface: #141B2F;
  --surface-raised: #18233C;
  --navy: #1E3A6E;
  --purple: #6B5CE6;
  --text: #E8ECF4;
  --muted: #8B95A8;
  --line: rgba(255,255,255,.08);
  --line-strong: rgba(255,255,255,.16);
  --cyan: #78C8D8;
  --danger: #F08B89;
  --success: #77D0A7;
  --warning: #E7BE78;
  --radius: 14px;
  --shadow: 0 18px 48px rgba(3, 8, 22, .28);
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: 82px; }
body { margin: 0; overflow-x: hidden; background: var(--bg); color: var(--text); font-family: "Pretendard Variable", Pretendard, "Noto Sans KR", sans-serif; line-height: 1.6; letter-spacing: -.02em; }
a { color: inherit; text-decoration: none; }
button, input, select, textarea { font: inherit; }
button, a { min-height: 44px; }
.container { --gutter: 20px; width: min(1180px, calc(100% - 40px)); margin: auto; }
.skip-link { position: fixed; z-index: 100; top: -80px; left: 16px; padding: 10px 16px; border-radius: 0 0 10px 10px; background: var(--purple); color: #fff; }
/* 건너뛰기 링크가 <main tabindex="-1"> 로 초점을 옮긴다. 초점 자체는 필요하지만
   판 전체에 테가 번쩍이면 안 되므로 테만 지운다(키보드 차례는 그대로다). */
main:focus { outline: none; }

.skip-link:focus { top: 0; }

.site-header { position: sticky; z-index: 50; top: 0; border-bottom: 1px solid var(--line); background: rgba(11,16,32,.92); }
.nav-wrap { height: 76px; display: flex; align-items: center; gap: 26px; }
/* ── 브랜드 로고 ─────────────────────────────────────────────────────
   회사 마크는 **등각 큐브**다 — 바깥 껍데기(속이 빈 육각 테두리)와 그 안에 든
   작은 큐브가 겹친 꼴. 한 장짜리 그림으로 두면 기울여 봐야 종이가 기우는 것으로
   읽히므로, 두 겹을 갈라 안쪽에 깊이를 준다. 돌릴 때 안쪽이 껍데기의 창 안에서
   어긋나 움직여 **상자 속을 들여다보는 것**이 된다 — 그게 3차원으로 읽히는 까닭이다.

   가만히 있을 때는 로고 그대로다. 손이 닿을 때만 돈다 —
   이유 없이 계속 떠다니면 그게 바로 "AI 가 만든 데모" 로 읽힌다.                */
.brand { display: inline-flex; align-items: center; gap: 9px; font-size: 1.06rem; font-weight: 900; white-space: nowrap; }
.brand-name { letter-spacing: -.015em; }
.brand-cube { position: relative; flex: none; width: 27px; height: 26px; perspective: 190px; }
.bc-rig { position: absolute; inset: 0; transform-style: preserve-3d;
  transform: rotateX(var(--bx, 0deg)) rotateY(var(--by, 0deg)) rotateZ(var(--bz, 0deg)); }
.brand-cube img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
/* 껍데기는 앞, 안쪽 큐브는 뒤 — 이 간격이 곧 상자의 깊이다 */
.bc-shell { transform: translateZ(3.5px); }
.bc-core  { transform: translateZ(-3.5px); }
.brand.is-live .bc-rig { will-change: transform; }

.footer .brand-cube { width: 25px; height: 24px; }

@media (prefers-reduced-motion: reduce) {
  .bc-rig { transform: none !important; }
  .bc-shell, .bc-core { transform: none !important; }
}
.site-nav { display: flex; align-items: center; gap: 21px; margin-left: auto; }
/* 49 행의 min-height:44px(손가락 넓이)가 글줄(27.1px)을 칸 맨 위에 앉힌다 —
   위 3.2 / 아래 20.8 로 글자만 9px 위로 떴다. 칸 안에서 가운데로 세운다.
   바닥 띄의 받기 단추(.mobile-beta)도 같은 방식이다. */
.site-nav a { display: flex; align-items: center; line-height: 1.25;
  font-size: .9rem; font-weight: 700; color: var(--muted); }
.site-nav a:hover, .site-nav a:focus-visible { color: var(--text); }

.language { display: inline-flex; align-items: center; gap: 3px; font-size: .76rem; color: var(--muted); white-space: nowrap; }
.hamburger { display: none; margin-left: auto; padding: 7px; border: 0; background: transparent; color: var(--text); font-size: 1.45rem; cursor: pointer; }

.hero, .page-hero { position: relative; overflow: hidden; isolation: isolate; }
.hero { padding: 112px 0 88px; background: radial-gradient(circle at 76% 38%, rgba(107,92,230,.18), transparent 35%), linear-gradient(110deg, #0B1020 0%, #101A34 53%, #1E3A6E 100%); }
/* 바탕은 한 벌 — 진한 남색. 밝은 파랑으로 끝나던 결은 쪽마다 다른 인상을 줬다.
   .is-room 이 쓰던 값을 모든 제목 화면으로 올린다(1019행은 그래서 지웠다). */
.page-hero { padding: 36px 0 30px; background: linear-gradient(150deg, #070B18 0%, #0B1020 58%, #131C36 100%); }
.neural-canvas { position: absolute; z-index: -1; inset: 0; width: 100%; height: 100%; opacity: .30; pointer-events: none; }
.hero:after, .page-hero:after { content: ""; position: absolute; z-index: -1; right: -18%; top: -45%; width: 70%; height: 150%; border-radius: 50%; border: 1px solid rgba(120,200,216,.08); transform: rotate(-24deg); pointer-events: none; }
.hero-grid { position: relative; z-index: 1; display: grid; grid-template-columns: 1.05fr .95fr; align-items: center; gap: 50px; }

/* ── 제목 화면의 키는 한 자리에서 정한다 ─────────────────────────────────
   탭을 옮길 때마다 첫 화면의 키가 359 · 391 · 557 · 557 로 널뛰었다.

   바닥값이 380 인 까닭 — 이 바닥은 «낮은 것을 밀어 올릴» 뿐 높은 것을 끌어내리지
   못한다. 그러니 어떤 무리를 같게 만들려면 바닥이 그 무리의 «가장 높은 속» 과
   같아야 한다. 탭 넷(소개 · 서비스 · 솔루션 · 문의)의 가장 높은 속은
   **국문 · 영문 · 1001~1600 어디서나 380**(서비스의 .hero-art 가 못 박힌 값)이라,
   380 이면 넷이 어느 폭 어느 언어에서나 정확히 같은 키로 선다.

   ⚠ 한때 412 로 두었다가 되돌렸다. 「열두 쪽 전부 같게」로 잡았던 값인데,
     그 412 를 **국문만 재서** 뽑았다. 영문은 글이 길어 속이 훌쩍 커진다 —
     ODMPASS 565(1100) · SNPVision 511 · FL-STUDIO 477. 두 언어를 함께 세우려면
     바닥이 565 여야 하고 그러면 키가 632 가 되어, 줄이려던 여백보다 더 커진다.
     재는 것은 반드시 두 언어로 해야 한다.

   ※ 전에는 이 줄을 문의.html 안에만 두고 「styles.css 에 적으면 안 된다」고
     적어 두었다. 그때는 «한 쪽만» 맞추는 일이라 남의 쪽이 따라 커지는 것이
     탈이었지만, 지금은 모두 같게 만드는 것이 시키는 일이라 판정이 뒤집혔다.
   ※ 한 칸으로 접히는 1000 아래에서는 걸지 않는다. 거기서는 속이 이미 380 을
     훌쩍 넘고(문의 625 · 마이디 877), 바닥을 깔아 봐야 빈 띠만 생긴다. */
@media (min-width: 1001px) {
  /* 속을 감싼 것은 어느 쪽이나 .container 다 — 두 칸으로 서는 쪽은 여기에
     .hero-grid 가 겹쳐 있을 뿐이다. 그래서 바닥 키는 .container 에 건다.
     .hero-grid 에만 걸면 격자가 아닌 둘(소개 · 솔루션)이 빠진다.
     마이주식은 2026-09-28 에 오른쪽 판이 생겨 격자로 옮겨 갔다. */
  /* 줄 높이를 1.3 으로 연 뒤 다시 쟀다 — 가장 큰 알맹이가 361(1001 국문 문의)로
     380 을 넘지 않는다. 바닥은 그대로 380 이다. */
  .page-hero > .container { min-height: 380px; }
  /* 격자는 이미 align-items: center 라 남는 키를 위아래로 나눠 갖는다. 격자가
     아닌 쪽은 블록이라 글이 위로 붙으므로, 그쪽만 가운데로 세운다. */
  .page-hero > .container:not(.hero-grid) {
    display: flex; flex-direction: column; justify-content: center;
  }
}
.eyebrow, .kicker { margin: 0 0 14px; color: var(--purple); font-size: .76rem; font-weight: 850; letter-spacing: .14em; text-transform: uppercase; }
/* 판(어두운 바탕) 위의 .kicker 는 브랜드 보라 그대로면 3.5:1 이라 작은 글씨
   기준(4.5:1)에 못 미친다. 밝기만 15% 들어 올려 4.6:1 로 맞춘다.
   .eyebrow 도 같다 — 「흰 바탕에 앉으니 두어도 된다」고 적어 뒀던 전제가
   이제 안 맞는다. 히어로 아홉 쪽에서는 어두운 판 위 3.53~3.89 였고, 흰
   바닥이던 되보내기 아홉 쪽도 판 안으로 들어와 어두워졌다. */
.kicker { color: #8174EA; }
.eyebrow { color: #8174EA !important; }   /* 7 행의 !important 를 이기려면 필요하다 */
/* 최대치가 5.5rem 이면 넓은 화면에서 히어로 첫 절("데이터를 옮기지 않고,")이 컬럼을
   넘칩니다 — 컨테이너는 1180px 에서 멈추는데 6vw 는 계속 커지기 때문입니다. 실측으로
   이 절의 폭은 글자 크기의 7.44배라, 좌측 컬럼 593px 에 여유 있게 들어가는 4.6rem 을
   상한으로 둡니다. 넘치면 "않고," 한 어절만 줄에 홀로 남습니다. */
/* 크기는 고객 서비스의 제목에 맞춘다 — 서비스.html 이 홀로 쓰던 clamp 를 올렸다.
   넓히는 것은 «줄 사이» 다. 글자 사이(letter-spacing)는 -.09em 그대로 둔다 —
   한 번 +.09em 으로 벌려 보았더니 글자가 낱낱이 흩어졌다(2026-09-23).
   줄 사이 흰 자리는 1.08 에서 대략 13px 이었다. 두 배인 27px 을 담으려면
   줄 높이가 1.3 이어야 한다(58.88px 글자 · 글자 몸통 0.85em 기준). */
.hero h1, .page-hero h1 { max-width: 780px; margin: 0 0 23px; font-size: clamp(2.2rem, 4.6vw, 3.7rem); line-height: 1.3; letter-spacing: -.09em; }
.hero h1, .page-hero h1 { background: linear-gradient(115deg, #fff 20%, #d9d4ff 92%); -webkit-background-clip: text; background-clip: text; color: transparent; }
/* 휴대폰 · 영문: 한글에 맞춘 자간(-.09em)이 낱말 사이 빈칸까지 줄여(35.2px 글자에 5px)
   'in one place' · 'AI solutions' 가 한 낱말처럼 붙어 읽혔다. 글자 사이와 줄 나눔은
   그대로 두고 낱말 사이만 본래 너비 가까이 되돌린다(5px → 7.4px).
   국문과 461px 이상은 건드리지 않는다. (2026-10-08)
   2026-10-12 760px → 460px. 낱말 사이가 넓어진 만큼 줄이 먼저 넘쳐, 폰보다 넓은 폭에서 제목이
   한 줄 길어진 쪽이 있었다 — 서비스 591~607px(두 줄 → 석 줄, 가운데 줄이 'up points' 뿐),
   마이주식 480px 안팎, snpbrain 516px 안팎.
   재어 고른 폭이 360 · 390 이었으니 폰 폭에서만 건다. 430 이 아니라 460 에서 끊는 까닭 —
   440px(아이폰 Pro Max) · 448px(픽셀 Pro XL)도 폰이다. 대신 소개 433~442px 과 snpvision
   451~460px 의 제목은 2026-10-08 이전보다 한 줄 길다(430px 폰에서와 같은 꼴).
   2026-10-12 폰 폭 안에도 같은 탈이 남아 있었다 — 낱말 사이 한 칸이 2.5px 씩 넓어져, 줄이 겨우 차던
   폭에서는 제목이 한 줄 늘었다(영문 열두 쪽 × 320~460px 1,692 칸 가운데 106 칸. 서비스 402px 은
   석 줄 → 넉 줄에 끝줄이 'community' 한 낱말, odmpass 402px 은 두 줄 → 석 줄). 값을 줄여도
   없어지지 않는다(.02em 에서도 25 칸) — 넓힌 만큼 먼저 넘치는 폭이 반드시 생긴다.
   그래서 넓혀도 길어지는 쪽이 드문 폭에서만 건다(크롬에서 1px 씩 잰 값, 양 끝 1px 여유):
     352~449px — 360 · 375 · 384 · 390 · 393 · 402 · 412 · 414 · 428 · 430 · 440 · 448 이 든다.
   뺀 폭과 그 까닭:
     351px 까지  소개 320~324 · 솔루션 320~323 · 329~335 · myd 320~326 · 마이주식 327~331 · myd-connect 338~345
                · 서비스 340~346 · odmpass 341~345 · 문의 342~346 · fl-studio 343~350
     450~460px  snpvision 451~460
   띠 안에서 탈이 나는 네 쪽은 제 쪽 머리의 style 에서 끈다 — catalogix 381~387px, 서비스 395~402px,
   odmpass 397~406px, 소개 433~442px.
   빠진 폭의 제목은 2026-10-08 이전의 낱말 사이로 돌아간다(줄 수는 그때와 같다).
   제목 글을 바꾸면 이 폭들을 다시 재야 한다. */
@media (min-width: 352px) and (max-width: 449px) {
  .hero h1:lang(en), .page-hero h1:lang(en) { word-spacing: .07em; }
}
.page-hero .lede { max-width: 680px; margin: 0; color: #B8C1D2 !important; font-size: 1.1rem; line-height: 1.72; }
.page-hero .lede { font-size: 1.15rem; }
.actions { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; margin-top: 32px; }
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; padding: 11px 18px; border: 1px solid transparent; border-radius: 11px; font-weight: 800; cursor: pointer; transition: transform .2s, box-shadow .2s, border-color .2s; }
/* 들림(translateY)은 위의 끌림과 같은 자리를 다투므로 그림자만 남긴다 —
   둘을 같이 쓰면 나중에 온 쪽이 이기고, 그 승패가 단추마다 갈렸다. */
.btn:hover { box-shadow: 0 10px 24px rgba(107,92,230,.18); }
.primary { background: var(--purple); color: #fff; }
.outline { border-color: var(--line-strong); background: transparent; color: var(--text); }
.outline:hover { border-color: rgba(107,92,230,.72); }
/* 밑줄을 기본으로 둔다 — 색만으로는 본문 글자와 1.40:1 이라 3:1 에 못 미치고,
   색을 못 가리는 사람에게는 링크가 보이지 않는다(WCAG 1.4.1). */
.text-link { padding-left: 2px; padding-right: 2px; border-radius: 0; color: #C8C2FF;
  text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
.text-link:hover { box-shadow: none; transform: none; text-decoration: underline; }
/* 문장 속 링크는 옆 안여백을 뗀다 (2026-10-08). 2px 가 밑줄 낱말과 뒤따르는 문장부호 사이를 벌려
   영문에서 'Solutions .' · 'ask us ,' 처럼 마침표 · 쉼표가 떨어져 보였고(링크 뒤 2px, 앞은 빈칸
   3.7px + 2px), 국문도 「솔루션 에서」 로 조사가 떨어졌다. 폭을 가리지 않는 탈이다. */
p .text-link { padding-left: 0; padding-right: 0; }
.trust-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 34px; }
.trust-chips span { padding: 7px 12px; border: 1px solid var(--line); border-radius: 99px; background: rgba(20,27,47,.74); color: var(--muted); font-size: .77rem; }

.hero-art { position: relative; min-height: 380px; }
.orb { position: absolute; inset: 32px 10px 12px 42px; border: 1px solid rgba(107,92,230,.35); border-radius: 45% 55% 52% 48%; background: linear-gradient(135deg, rgba(30,58,110,.42), rgba(107,92,230,.11)); box-shadow: var(--shadow); transform: rotate(-8deg); }
.orb:before, .orb:after { content: ""; position: absolute; border-radius: 50%; }
.orb:before { right: 40px; top: 28px; width: 180px; height: 180px; background: rgba(107,92,230,.15); }
.orb:after { bottom: 30px; left: 58px; width: 120px; height: 120px; background: rgba(120,200,216,.08); }
.visual-card { position: absolute; padding: 16px 18px; border: 1px solid var(--line); border-radius: 13px; background: var(--surface); box-shadow: var(--shadow); }
.visual-card small { display: block; color: var(--muted); font-size: .7rem; }
.visual-card strong { display: block; margin-top: 5px; }
.visual-card.one { top: 44px; left: 0; width: 190px; }
.visual-card.two { top: 158px; right: 0; width: 220px; }
.visual-card.three { bottom: 0; left: 65px; width: 235px; }

.section { padding: 106px 0; }
.section-white { background: var(--surface); }
.section-head { display: flex; align-items: end; justify-content: space-between; gap: 30px; margin-bottom: 34px; }
.section h2 { max-width: 730px; margin: 0; font-size: clamp(2rem, 4vw, 3.3rem); line-height: 1.12; letter-spacing: -.075em; }
/* 휴대폰 · 영문: 위 .page-hero h1 과 같은 까닭이다 — 자간 -.075em 이 낱말 사이까지 줄여
   'the moment you log in' 이 한 덩어리로 붙어 읽혔다. 낱말 사이만 되돌린다
   (32px 글자에 5px → 7.2px). 국문과 761px 이상은 그대로다. (2026-10-08)
   2026-10-12 첫 화면 제목과 같은 탈 — 넓어진 낱말 사이 탓에 줄이 겨우 차던 폭에서 구역 제목이
   한 줄(odmpass 366~374px 은 두 줄) 늘었다. 영문 구역 제목 스물한 개 × 320~760px 9,261 칸 가운데
   115 칸, 제목 열 개. 값을 줄여도 남는다(.03em 에서 46 칸).
   넓혀도 길어지는 제목이 드문 폭에서만 건다(크롬에서 1px 씩 잰 값, 양 끝 1px 여유).
   뺀 폭과 그 까닭:
     352px 까지  myd-connect 'This is what you see…' 320~325 · 343~351, odmpass 'Open only what you are…' 320~321,
                fl-studio 'Open only the explanation…' 334~338, 솔루션 'Six products…' 343~349,
                snpvision 'What the camera saw…' 346~351
     463~475px  snpvision 'What the camera saw…' 464~472, fl-studio 'Products worth seeing together' 468~474
     517~529px  fl-studio 'Open only the explanation…' 518~528
     542~556px  odmpass 'Open only what you are curious about' 543~555
   띠 안에서 길어지는 제목 넷은 제 쪽 머리의 style 에서 그 제목만 끈다(375 · 384 · 428 · 430px 폰에서
   나머지 제목의 낱말 사이를 지키려고) — odmpass #fact-h 365~376, 서비스 #pillars-h 375~383,
   문의 #privacy-h 381~387, 솔루션 #principle-h 419~430.
   빠진 폭의 제목은 2026-10-08 이전의 낱말 사이로 돌아간다. 제목 글을 바꾸면 다시 재야 한다. */
@media (min-width: 353px) and (max-width: 462px), (min-width: 476px) and (max-width: 516px),
       (min-width: 530px) and (max-width: 541px), (min-width: 557px) and (max-width: 760px) {
  .section h2:lang(en) { word-spacing: .07em; }
}
.section-intro { max-width: 470px; margin: 0; color: var(--muted); }

.product-group-head { display: flex; align-items: baseline; justify-content: space-between; gap: 20px; margin-bottom: 17px; }
.product-group-head h3 { margin: 0; font-size: 1.3rem; }
.product-group-head p { margin: 0; color: var(--muted); font-size: .86rem; }
.product-card { min-height: 350px; padding: 20px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface-raised); display: flex; flex-direction: column; scroll-snap-align: start; }
/* 22 행이 border-color 를 !important 로 못박아 이 규칙은 한 픽셀도 못 그렸다
   (!important 는 특이도보다 먼저 판가름한다). 같은 무게로 올린다. 넷 중
   HTML 에 실제로 있는 것은 .distinction 하나뿐이라 나머지 셋은 걷었다. */
.distinction:hover { border-color: rgba(107,92,230,.5) !important; }
.product-card.featured { grid-column: span 2; min-height: 380px; border-color: rgba(107,92,230,.58); background: linear-gradient(145deg, #1A2D55, #2B2660); color: var(--text); }
.badge.ready { background: rgba(119,208,167,.14); color: #96E2BE; }
.product-card h4 { margin: 0 0 6px; font-size: 1.3rem; letter-spacing: -.05em; }

.tech-card { min-height: 230px; padding: 25px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
.tech-card h3 { margin: 28px 0 8px; font-size: 1.35rem; }
.tech-card p { margin: 0; color: var(--muted); font-size: .92rem; }
.tech-card small { display: block; margin-top: 10px; color: #BFB9FF; font-weight: 700; }

.trust { background: #101A34; color: var(--text); }
.trust .kicker { color: #BFB9FF; }
.trust-highlights { display: grid; grid-template-columns: 1fr 1fr; gap: 11px; }
.trust-item { padding: 19px; border: 1px solid var(--line); border-radius: 13px; background: rgba(20,27,47,.68); }
.trust-item strong { display: block; font-size: 1.04rem; }
.trust-item span { color: var(--muted); font-size: .78rem; }
.news-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.news-card { padding: 17px; border: 1px solid var(--line); border-radius: 13px; background: var(--surface); }
.news-card small { color: #BFB9FF; font-size: .7rem; }
.news-card p { margin: 10px 0 0; font-weight: 750; }

.faq-question span { color: #BFB9FF; font-size: 1.35rem; transition: transform .2s; }
.faq-answer.open { display: block; }
.contact { background: var(--bg); }
/* 머리 번호는 다른 쪽과 같은 보라. .contact-copy p 가 .kicker 보다 세서
   여기서만 회색으로 깔리고 있었다. */
.contact-copy p:not(.kicker) { color: var(--muted); }
.contact-grid { display: grid; grid-template-columns: .72fr 1.28fr; gap: 60px; }
.contact-form, .beta-form { display: grid; grid-template-columns: 1fr 1fr; gap: 15px; }
.form-field { position: relative; }
.form-field.full, .form-consent, .form-actions, .form-status { grid-column: 1 / -1; }
.form-field label, .form-consent label { display: block; font-size: .79rem; font-weight: 800; }
.required { color: #BFB9FF; }
.form-field input, .form-field select, .form-field textarea { display: block; width: 100%; margin-top: 6px; padding: 11px 13px; border: 1px solid var(--line-strong); border-radius: 9px; background: var(--surface); color: var(--text); outline: none; }
.form-field select option { background: var(--surface); color: var(--text); }
.form-field textarea { min-height: 125px; resize: vertical; }
.form-field input:focus, .form-field select:focus, .form-field textarea:focus { border-color: var(--purple); box-shadow: 0 0 0 3px rgba(107,92,230,.2); }
.field-error { min-height: 18px; margin: 3px 0 0; color: var(--danger); font-size: .74rem; font-weight: 600; }
.is-invalid input, .is-invalid select, .is-invalid textarea { border-color: var(--danger); }
.form-consent input { width: 18px; height: 18px; margin: 0 7px 0 0; vertical-align: -4px; accent-color: var(--purple); }
/* 동의 줄 — 체크박스가 혼자 한 줄을 차지하고 문장은 그 아랫줄에서 시작해 한 묶음으로 읽히지
   않던 것 (2026-10-08). 위 .form-field label 과 묶인 display: block 이 이 라벨에도 걸려 있었다 —
   바로 윗줄의 margin-right · vertical-align 은 옆에 나란히 세우려던 값이다. 폭을 가리지 않는 탈이라
   (1440 에서도 같았다) 여기서 푼다. */
.form-consent label { display: inline; color: var(--muted); }
.form-actions { display: flex; align-items: center; gap: 14px; }
.form-actions .btn { min-width: 120px; }
.form-actions .btn[disabled] { cursor: wait; opacity: .68; }
/* 라이브 영역은 «처음부터 트리에 있어야» 한다 — display:none 으로 두면 낭독기가
   나중에 넣은 글을 못 읽는다. 자리만 접고 보이지 않게 둔다. */
.form-status { visibility: hidden; height: 0; overflow: hidden; padding: 0 15px;
  border-radius: 9px; font-size: .84rem; }
.form-status.show { visibility: visible; height: auto; padding: 13px 15px; }
.form-status.success { background: rgba(119,208,167,.12); color: #96E2BE; }
.form-status.failure { background: rgba(240,139,137,.12); color: #F3A5A3; }
.success-panel { display: none; padding: 24px; border: 1px solid rgba(119,208,167,.35); border-radius: 13px; background: rgba(119,208,167,.08); }
.success-panel.show { display: block; }
.success-panel h3 { margin: 0 0 6px; }
.success-panel p { margin: 0; color: var(--muted); }

.footer { padding: 56px 0 28px; background: #0D1428; color: #B7C0D1; }
/* 첫 칸은 브랜드와 «회사 정보 · 주소» 를 함께 담는다. 주소 다섯 줄 가운데
   가장 긴 것이 379px 이라 그만큼은 있어야 한 줄로 들어간다 —
   1.74fr 이면 1280 에서 400px 이다(1.25fr 은 321px 이라 두 줄로 접혔다). */
/* 회사 정보 한 칸 + 탭 넷(소개 · 서비스 · 솔루션 · 문의). 머리띠의 차례와 같다. */
.footer-grid { display: grid; grid-template-columns: 1.9fr 1fr 1fr 1fr 1fr; gap: 30px; }
.footer .brand { color: var(--text); }
.footer h3 { margin: 0 0 11px; color: var(--text); font-size: .82rem; }
.footer p, .footer a { color: var(--muted); font-size: .78rem; }
.footer a:hover { color: var(--text); }
/* 푸터 링크 줄 간격은 원래대로 둔다(2026-09-28, 담당자 요청).
   한때 <br> 을 걷고 링크를 한 칸씩 세워 손가락 자리를 27px 로 키웠는데,
   줄 사이가 너무 벌어져 되돌렸다. 손가락 자리는 21x15 로 WCAG 2.2 AA(24x24)에
   못 미친다 — 아는 채로 둔 자리다. */
/* 휴대폰: 보이는 줄 간격(20px)은 위 결정대로 두고 누르는 면만 넓힌다 — 링크가 제 줄을
   통째로 차지하게 세우고 <br> 을 접는다. 글자는 제자리(줄 간격 19.97px 그대로),
   누르는 면은 21x15 → 칸 너비x20 이고 줄 사이 죽은 틈 5px 이 없어진다.
   24px 을 넘기려면 줄 사이를 벌려야 해서 거기까지는 가지 않았다. (2026-10-08) */
@media (max-width: 760px) {
  .footer-grid p a { display: block; min-height: 0; }
  .footer-grid p br { display: none; }
}
.footer-bottom { display: flex; justify-content: space-between; gap: 20px; margin-top: 34px; padding-top: 20px; border-top: 1px solid var(--line); color: #7B8599; font-size: .72rem; }
.mobile-beta { display: none; }

.distinction { padding: 25px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface-raised); }
.distinction h3 { margin: 28px 0 8px; }
.distinction p { margin: 0; color: var(--muted); font-size: .9rem; }
.screen-placeholder { min-height: 260px; padding: 22px; border: 1px dashed rgba(107,92,230,.55); border-radius: 15px; background: linear-gradient(140deg, #141B2F, #182744); color: var(--muted); display: flex; flex-direction: column; justify-content: space-between; }
.screen-placeholder strong { font-size: 1.1rem; color: var(--text); }
.screen-placeholder span { align-self: center; font-size: 3rem; color: #BFB9FF; }
.permission-note { max-width: 780px; padding: 20px 22px; border-left: 4px solid var(--purple); background: rgba(107,92,230,.1); color: #BAC4D7; }
/* 판 안에서 끝맺는 단추 줄. 전에는 제 판(.split-cta)을 따로 써서 단추만
   아래로 떨어져 나와 어색했다 — 앞 판의 통 안으로 들였다. */
.end-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 38px; }
.end-actions a { display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 13px 24px; border: 1px solid var(--line); border-radius: 11px;
  font-size: .97rem; font-weight: 800; color: var(--text);
  transition: transform .2s var(--spring), border-color .2s, background .2s, box-shadow .28s var(--settle); }
.end-actions a:last-child { border-color: transparent; background: var(--purple); color: #fff; }
.end-actions a:hover { transform: translateY(-2px); border-color: rgba(107,92,230,.5); }
.end-actions a:last-child:hover { box-shadow: 0 10px 24px rgba(107,92,230,.28); }
/* 받기가 둘이면 마지막 하나만 칠하는 위 규칙으로는 모자란다 — 마이주식은
   App Store 와 원스토어 둘이다. 표시를 단 것은 자리와 상관없이 같은 빛깔로 칠한다. */
.end-actions a.primary { border-color: transparent; background: var(--purple); color: #fff; }
.end-actions a.primary:hover { box-shadow: 0 10px 24px rgba(107,92,230,.28); }
@media (max-width: 760px) { .end-actions a { flex: 1 1 100%; } }
.prototype-note { padding: 13px 15px; border-left: 3px solid var(--purple); background: rgba(107,92,230,.1); }

@media (max-width: 1000px) {
  /* minmax(0,…) 다 — 맨 `1fr` 은 `minmax(auto, 1fr)` 이라 트랙의 최소값이 속의
     min-content 를 따라간다. 속에 nowrap 글씨가 있으면 영문에서 칸이 늘어나
     쪽이 넘친다(계기판 타일에서 331 → 370px 이었다). 0 으로 못 박는다. */
  .hero-grid { grid-template-columns: minmax(0, 1fr); }
  .product-card.featured { grid-column: span 2; }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  /* 두 칸으로 접히면 첫 칸을 줄 전체로 벌린다 — 반 칸(390 에서 150px)에
     주소를 넣으면 다섯 줄이 열 줄을 넘는다. */
  .footer-grid > div:first-child { grid-column: 1 / -1; }
  .contact-grid { gap: 35px; }
}
@media (max-width: 760px) {
  .container { --gutter: 16px; width: calc(100% - 32px); }
  .nav-wrap { height: 68px; }
  /* top 은 68px 이었다 — 1675행이 좁은 화면 머리띠를 76px 로 못박은 뒤로는
     서랍이 머리띠를 8px 파고들었다. 숫자를 다시 적는 대신 통(.nav-wrap,
     1684행에서 position:relative)의 아래끝에 붙여 키가 바뀌어도 따라가게 한다. */
  .site-nav { display: none; position: absolute; top: 100%; left: 0; right: 0; align-items: stretch; flex-direction: column; gap: 0; padding: 9px 16px 17px; background: var(--surface); border-bottom: 1px solid var(--line); box-shadow: 0 16px 30px rgba(3,8,22,.3); }
  .site-nav.open { display: flex; }
  .site-nav a { padding: 11px 4px; border-bottom: 1px solid var(--line); }
  .language { margin-left: auto; }
  .hamburger { display: block; }
  .hero { padding: 75px 0 62px; }
  .actions { gap: 12px; }
  .hero .actions .primary, .hero .actions .outline { flex: 1 1 calc(50% - 12px); }
  .hero .actions .text-link { flex-basis: 100%; justify-content: flex-start; }
  .hero-art { min-height: 285px; transform: scale(.9); transform-origin: left top; }
  .section, .page-hero { padding: 74px 0; }
  .page-hero { padding: 28px 0; }
  .section-head { display: block; margin-bottom: 27px; }
  .section-intro { margin-top: 14px; }
  .news-grid { grid-template-columns: 1fr; }
  .product-group-head { display: block; }
  .product-group-head p { margin-top: 4px; }
  .product-card, .product-card.featured { flex: 0 0 min(84vw, 340px); min-height: 350px; grid-column: auto; }
  .product-card.featured { min-height: 380px; }
  .trust-highlights { grid-template-columns: 1fr 1fr; }
  .final-inner .actions { margin-top: 22px; }
  .contact-grid { grid-template-columns: 1fr; gap: 28px; }
  .contact-form, .beta-form { grid-template-columns: 1fr; }
  .form-field.full, .form-consent, .form-actions, .form-status { grid-column: auto; }
  /* 동의 줄의 손가락 자리 (2026-10-08) — 체크박스는 18px, 글줄은 20px 라 누를 데가 낮았다.
     보이는 것은 그대로 두고 라벨이 «받는» 자리만 넓힌다: 글자 상자 15px 에 위 22px · 아래 8px 를
     더해 45px, 왼쪽으로는 체크박스 위까지(18 + 7 = 25px). 줄 안 상자의 위아래 안여백은 줄 높이를
     바꾸지 않는다. 아래를 덜 준 것은 5px 밑이 바로 안내 글(링크)이라서다 — 위는 15px 빈 틈이다. */
  .form-consent label { margin-left: -25px; padding: 22px 0 8px 25px; }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  /* 두 칸으로 접히면 첫 칸을 줄 전체로 벌린다 — 반 칸(390 에서 150px)에
     주소를 넣으면 다섯 줄이 열 줄을 넘는다. */
  .footer-grid > div:first-child { grid-column: 1 / -1; }
  .footer-bottom { display: block; }
  .footer-bottom span { display: block; margin-top: 8px; }
  .mobile-beta { position: fixed; display: flex; align-items: center; justify-content: center; left: 14px; right: 14px; bottom: 14px; z-index: 45; min-height: 50px; border-radius: 11px; background: var(--purple); color: #fff; font-weight: 850; box-shadow: 0 12px 30px rgba(3,8,22,.35); }
  body { padding-bottom: 76px; }
  .page-hero .actions .btn { width: 100%; }
  .screen-placeholder { min-height: 210px; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { scroll-behavior: auto !important; transition: none !important; }
  .btn:hover { transform: none; }
}

/* Multi-page prototype components */
.page-section { padding: 92px 0; }
.page-section.alt { background: var(--surface); }
.page-section.navy { background: #101A34; }
.card-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.info-card { padding: 25px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface-raised); }
.info-card:hover { border-color: rgba(107,92,230,.55); transform: translateY(-2px); }
.info-card { transition: border-color .2s, transform .2s; }
.info-card h3 { margin: 16px 0 8px; font-size: 1.25rem; }
.info-card p { margin: 0; color: var(--muted); }
.card-label, .article-meta { color: #BFB9FF; font-size: .75rem; font-weight: 850; letter-spacing: .08em; }
.card-link { display: inline-flex; margin-top: 20px; color: #C8C2FF; font-weight: 800; font-size: .86rem; }
.product-list-card { min-height: 300px; padding: 22px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface-raised); display: flex; flex-direction: column; }
.product-list-card[hidden] { display: none; }
.product-list-card h3 { margin: 18px 0 7px; }
.product-list-card p { margin: 0; color: var(--muted); font-size: .92rem; }
.product-list-card .card-link { margin-top: auto; }
.pillar-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.pillar-card { min-height: 305px; padding: 28px; border: 1px solid var(--line); border-radius: var(--radius); background: linear-gradient(150deg, var(--surface-raised), #1D2B4A); }
.pillar-card h3 { margin: 32px 0 10px; font-size: 1.5rem; }
.pillar-card p { color: var(--muted); }
.pillar-card ul { margin: 20px 0 0; padding-left: 18px; color: #C7D0E0; }
.timeline { display: grid; gap: 12px; }
.news-article .card-link { margin-top: auto; }
@media (max-width: 760px) { .page-section { padding: 68px 0; } .card-grid, .product-list-grid, .pillar-grid { grid-template-columns: 1fr; } .timeline-item { grid-template-columns: 1fr; gap: 7px; } .product-detail-grid { grid-template-columns: 1fr; } }

/* Current nav + 시작하기 theme cards */
/* 지금 보고 있는 탭 — 손을 치워도 그대로 남는다: 진한 글씨 · 굵게.
   나머지 탭은 회색이고 손이 닿을 때만 밝아진다.
   !important 를 쓰는 까닭 — 이 파일 19행의 테마 강제 블록이
   `.site-nav a{color:var(--muted)!important}` 로 못박아 두어서, 그것을 이기지
   못하면 켜진 탭도 회색으로 남는다(손이 닿아도 밝아지지 않았다). */
.site-nav a:hover, .site-nav a:focus-visible { color: var(--text) !important; }
.site-nav a.cur,
.site-nav a[aria-current="page"] { color: #fff !important; font-weight: 850; }
/* 굵기는 아래 1738 행 `.site-header .site-nav a:not(.nav-beta){font-weight:750}`
   (0,3,1) 에 져서 안 먹었다 — 보라 밑줄을 걷고 나면 «색 하나» 만 남아 표시가
   너무 옅다. 자리를 적어 굵기를 살린다. */
.site-header .site-nav a.cur:not(.nav-beta),
.site-header .site-nav a[aria-current="page"]:not(.nav-beta) { font-weight: 900; }
/* 지금 쪽 표시 밑줄 — 맨 윗줄 탭에만, «상자» 가 아니라 «글자» 아래에 긋는다.
   «.site-nav 안의 a[aria-current]» 로 짚으면 펼침 목록(회사 · 연혁 · …)의
   항목도 같이 걸려 세부 탭 밑에도 줄이 그어진다. 세부 탭은 제 표시가 따로
   있다(연한 보라 바탕). 그래서 직계 자식으로 못 박는다.
   전에 탈이 났던 것은 밑줄의 «자리» 였다: inset box-shadow 는 상자 맨 아래에
   붙는데 그 상자는 손가락이 짚을 넓이(49 행 min-height:44px)라, 글자에서
   11px 떨어진 자리에 선이 홀로 떠 있었다.
   ::after 로 자리를 잡으면 링크가 position:relative 가 되어야 하는데 그러면
   메뉴통(position:absolute)의 폭 셈에서 지금 쪽 링크가 빠져 칸들이 겹친다.
   그래서 «바탕 그림 한 줄» 로 긋는다 — 자리를 안 잡고도 글자 바로 아래에 온다. */
.site-header .nav-main > a.cur:not(.nav-beta),
.site-header .nav-main > a[aria-current="page"]:not(.nav-beta),
.site-header .nav-drop > a.cur,
.site-header .nav-drop > a[aria-current="page"] {
  background-image: linear-gradient(var(--purple), var(--purple));
  background-repeat: no-repeat;
  background-size: 100% 3px;
  background-position: 0 calc(100% - 7px);
}

/* 언어 고르개 — 누르면 상단 탭 이름이 한/영으로 오간다(본문은 국문 그대로). */
.lang-btn { min-height: 0; padding: 3px 6px; border: 0; border-radius: 7px; background: none;
  color: var(--muted); font-size: .76rem; font-weight: 800; letter-spacing: .02em; cursor: pointer;
  transition: color .18s, background .18s; }
.lang-btn:hover, .lang-btn:focus-visible { color: var(--text); }
.lang-btn.is-on { color: #fff; background: rgba(107,92,230,.3); }
.language i { font-style: normal; opacity: .45; }
/* 휴대폰: KR · EN 은 28x25px 이고 둘 사이가 10px 이라 골라 누르기 빠듯했다. 보이는
   알약은 그대로 두고 ::after 로 누르는 면만 넓힌다 — 위아래 10px, 바깥쪽 10px,
   서로 마주 보는 쪽은 4px(틈 10px 을 나눠 갖는다). 약 42x45px 이 된다. (2026-10-08)
   2026-10-12 — 손가락으로 쓰는 넓은 화면(태블릿 768 · 820 등)에서도 누르는 면이 28x25px 그대로였다.
   폭뿐 아니라 손가락(pointer: coarse)으로도 걸리게 한다. 보이는 알약은 그대로고, 마우스 화면은 닿지 않는다. */
@media (max-width: 760px), (pointer: coarse) {
  .lang-btn { position: relative; }
  .lang-btn::after { content: ""; position: absolute; inset: -10px -4px; }
  .lang-btn[data-lang="ko"]::after { left: -10px; }
  .lang-btn[data-lang="en"]::after { right: -10px; }
}
.brand.cur { color: var(--text); }

.launcher .wrap-narrow { max-width: 920px; margin: 0 auto; }
.lede { color: var(--muted); }
.grid.cards, .launcher-grid {
  display: grid;
  gap: 12px;
}
@media (min-width: 700px) {
  .launcher-grid { grid-template-columns: repeat(2, 1fr); }
}
a.card {
  display: block;
  text-decoration: none;
  color: inherit;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 18px 20px;
  transition: border-color .15s, transform .15s;
  min-height: 0;
}
a.card:hover {
  border-color: rgba(107,92,230,.45);
  transform: translateY(-1px);
}
a.card b, a.card .card-title {
  display: block;
  font-size: 1.05rem;
  margin-bottom: 4px;
}
a.card span {
  color: var(--muted);
  font-size: .9rem;
}
a.card.primary, a.launcher-card.primary {
  border-color: rgba(107,92,230,.55);
  background: linear-gradient(135deg, rgba(30,58,110,.55), rgba(107,92,230,.25));
}
.launcher .note { margin-top: 28px; font-size: .85rem; color: var(--muted); }

/* launcher helpers */.launcher .lede{max-width:52ch}.launcher-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}@media(max-width:650px){.launcher-grid{grid-template-columns:1fr}}

/* === 보조 문구 · 상태 알약 ============================================= */
/* 스크린리더에만 읽히는 보조 문구 — "(새 창)" 처럼 시각적으로는 화살표가 대신한다. */
/* 화살표는 글자가 아니라 «표» 라서 제 자리가 글자와 다르다. Pretendard 를
   2048 단위로 재어 그만큼만 내리고 당긴다.
     ↗  잉크 아래 +362 (밑줄 위에 떠 있다) · 오른쪽 여백 406
     →  잉크 아래   -2 (밑줄에 붙어 있다) · 오른쪽 여백 182
     ↓  잉크 아래   -8 (밑줄에 붙어 있다) · 오른쪽 여백 298
   글자의 오른쪽 여백은 36~98 뿐이라, 화살표가 끝에 서면 그 차이가 그대로
   「오른쪽이 더 넓다」로 보인다. 내리는 것은 ↗ 하나뿐이다 — 나머지 둘은
   이미 밑줄에 앉아 있어 내리면 오히려 글자 밑으로 내려간다.
   transform 이 아니라 position·top 을 쓰는 까닭 — 줄글 속 링크의 화살표는
   인라인이라 transform 이 통하지 않는다. */
.ar-ne { position: relative; top: .177em; margin-right: -.198em; }
.ar-e { margin-right: -.089em; }
.ar-s { margin-right: -.146em; }

/* 쪽 안에서 건너뛰는 띠 — 오른쪽 가장자리, «머리띠 아래 칸» 의 한가운데.
   전에는 창 한가운데(top:50%)에 두었는데, 그 자리는 흰 머리띠까지 센 값이라
   남색 판만 놓고 보면 늘 위로 치우쳐 보였다(머리띠 93px → 46px 위).
   머리띠 높이는 app.js 가 --hd 로 내려 준다. 가운데 = 50% + 머리띠/2 다.
   띠가 남색 판의 오른쪽 모서리에 걸쳐 서는 것은 그대로 둔다 — 제 판을 깔고
   있어 남색 위에서도 흰 여백 위에서도 읽힌다. */
.jumprail {
  position: fixed; z-index: 44; right: var(--gut, 21px);
  top: calc(50% + var(--hd, 93px) / 2);
  /* 오른쪽 끝을 판 모서리에 붙인 뒤 제 너비의 절반만큼 되민다 — 띠의
     가운데가 남색과 흰색의 경계에 얹힌다. 창이 좁아 절반이 여백보다
     크면 창 밖으로 나가므로 미는 양을 여백-4px 로 묶는다. */
  transform: translate(min(50%, calc(var(--gut, 21px) - 4px)), -50%);
  display: flex; flex-direction: column; gap: 2px;
  padding: 8px; border: 1px solid rgba(255,255,255,.10); border-radius: 99px;
  background: rgba(14,20,37,.82); backdrop-filter: blur(8px);
  transition: opacity .35s;
}
.jumprail button {
  display: flex; align-items: center; justify-content: center;
  border: 0; background: none; cursor: pointer; font: inherit;
  transition: color .25s, opacity .25s, background .25s;
}
.jumprail.is-gone { opacity: 0; pointer-events: none; }

/* 제품 건너뛰기 — 이름 둘이 늘 보이고, 지금 있는 쪽만 진하다. */
.svcjump button {
  padding: 7px 13px; border-radius: 99px;
  color: var(--muted); font-size: .73rem; font-weight: 800; letter-spacing: -.02em;
  white-space: nowrap; opacity: .62;
}
.svcjump button.is-on { color: var(--text); background: rgba(107,92,230,.22); opacity: 1; }
.svcjump button:hover, .svcjump button:focus-visible { opacity: 1; }

/* 위아래 건너뛰기 — 「여기서 더 갈 수 있다」 를 화살표로 알린다. */
.dirjump button { width: 30px; height: 30px; border-radius: 50%; color: var(--text); }
.dirjump button:hover, .dirjump button:focus-visible { background: rgba(107,92,230,.22); }
.dirjump button[disabled] { opacity: .3; cursor: default; }
.dirjump svg { width: 15px; height: 15px; }

@media (max-width: 760px) {
  .jumprail { padding: 6px; }
  .svcjump button { padding: 6px 10px; font-size: .68rem; }
  /* 화살표 단추는 폭이 26px 이라 띠(40px)의 양옆 7px 이 눌러도 답이 없는 자리였다.
     ::after 로 누르는 면을 띠 너비까지 넓힌다 — 보이는 것은 그대로다. (2026-10-08) */
  .dirjump button { position: relative; width: 26px; height: 26px; }
  .dirjump button::after { content: ""; position: absolute; inset: 0 -7px; }
}
@media (prefers-reduced-motion: reduce) { .jumprail, .jumprail button { transition: none; } }

.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }

.chat-status { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px; border-radius: 99px; background: rgba(107,92,230,.18); color: #C8C2FF; font-size: .72rem; font-weight: 800; white-space: nowrap; }
.chat-status i { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }

/* === 문장마다 한 줄 =====================================================
   긴 설명은 한 덩이로 뭉쳐 있으면 읽다가 어디까지 봤는지 놓칩니다. 문장이
   끝나는 자리에서 줄을 나눠 눈이 쉴 자리를 만듭니다.

   <br> 을 쓰지 않는 까닭 — 좁은 화면에서는 문장 자체가 접히는데, 그때 <br>
   은 그 앞에 어정쩡하게 짧은 줄을 남깁니다. 블록 span 이면 문장 단위만
   지켜지고 접히는 것은 문장 안에서 일어납니다.                          */
.ln { display: block; }
.ln + .ln { margin-top: .32em; }

/* === 한글 줄바꿈 — 어절 단위 ============================================
   브라우저 기본값은 한글을 낱자 사이 아무 데서나 끊습니다("데이터를 옮기지 않
   고" 가 "않 / 고" 로 갈라짐). keep-all 로 띄어쓰기(어절) 자리에서만 줄이 바뀌게
   하고, 끊을 자리가 없는 긴 URL·영문만 예외로 넘깁니다.
   text-wrap 은 마지막 줄에 한 어절만 남는 모양을 막아 줍니다.            */
html { word-break: keep-all; overflow-wrap: break-word; }
h1, h2, h3, h4, h5, .hero h1, .page-hero h1, .section h2 { text-wrap: balance; }
p, li, dd, figcaption, .lede, .section-intro { text-wrap: pretty; }
/* 휴대폰 · 영문 첫 화면 제목: balance 는 <br> 앞 토막만 고르고(크롬) 뒤 토막은 그냥 흘려
   마지막 줄에 낱말 하나만 남았다 — 'on a blurred / image', 'already / is'.
   pretty 는 <br> 뒤 토막의 끝줄 외톨이도 막는다. 모르는 브라우저는 이 줄을 버리고
   위의 balance 로 남는다. 국문과 461px 이상은 그대로다. (2026-10-08)
   2026-10-12 760px → 460px. 제목의 낱말 사이 규칙(.hero h1:lang(en) 의 word-spacing)과 한 짝이라
   같은 폭에서 끊는다 — 461~760px 은 2026-10-08 이전의 줄 나눔(balance)으로 돌아간다.
   pretty 만 남기면 서비스 472~590px 의 '…builds / up points' 가 그대로다.
   2026-10-12 낱말 사이 규칙은 폭 띠로 좁혔지만 이 줄은 460px 이하 그대로 둔다 — pretty 는 줄을
   늘리지 않는다(영문 열두 쪽 × 320~460px 1,692 칸 가운데 0 칸). 끝줄에 한 낱말이 남는 자리는
   서비스 320~394px('…and makes a / community')뿐이었고, balance 로도 낱말 사이를 바꿔도 못 피한다
   (2026-10-08 이전에도 같았다) — 그 자리는 서비스.html 제목의 data-en 에 줄바꿈 없는 빈칸을 넣어
   'and makes / a community' 로 막았다. */
@media (max-width: 460px) {
  .hero h1:lang(en), .page-hero h1:lang(en) { text-wrap: pretty; }
}
code, pre { word-break: break-all; }

/* === 갈리면 안 되는 묶음 — 휴대폰 (2026-10-08) ==========================
   keep-all 은 어절 사이라면 어디서든 줄을 바꿉니다. 그래서 320~412px 제품 쪽
   본문에서 한 덩이로 읽혀야 할 말이 두 줄로 갈렸습니다 — 「100P / 가 붙습니다」
   (띄어 쓴 조사), 「[거래 > / 포인트]」(메뉴 경로), 「쇼핑 / (쿠팡)」「/ · 건강(…)」
   (괄호와 줄 머리 가운뎃점), 「검색· / 요약·생성하는」, 「제 / 모양」「그 / 안에서」
   (한 글자 꾸밈말), 영문 'the App / Store' · '1 / month'.
   그런 자리만 마크업에서 .nb-m 으로 묶습니다. 761px 부터는 아무 일도 하지 않으므로
   넓은 화면의 줄은 그대로입니다. 묶음은 짧게 잡습니다 — 320px 판의 탭 글 폭이
   202px 이라 그보다 길면 칸을 넘칩니다. */
@media (max-width: 760px) { .nb-m { white-space: nowrap; } }
/* 한 덩어리로 넘어가야 하는 것(신고 번호 · 붙임표 든 지명)을 묶는다. 붙임표 뒤는
   줄을 바꿀 수 있는 자리라 영문 바닥글과 연락처 카드에서 '2-01- / 20-0274',
   'Seocho- / gu' 로 갈렸다. 국문 줄은 한 줄에 들어가 쓰지 않는다. (2026-10-08) */
.nb { white-space: nowrap; }

/* 히어로 브랜드 서명 — 문서 1 §5 C안. H1(B안) 아래에 현행 홈페이지 문구(A안)를
@media (max-width: 760px) { .hero-sign { margin: -8px 0 16px; font-size: .92rem; } }

/* === 메인 스크롤 스토리 =================================================
   첫 화면부터 영상처럼 재생되고, 스크롤이 재생 헤드가 된다. 무대는 sticky 로
   붙어 있고 그 뒤의 긴 트랙을 지나가는 동안 네 장면이 바뀐다.
   진행도는 JS 가 --p (0~1) 로, 장면은 data-scene 으로 넘긴다.            */
.story { position: relative; background: radial-gradient(circle at 70% 24%, rgba(107,92,230,.18), transparent 42%), linear-gradient(178deg, #0B1020 0%, #101A34 62%, #0B1020 100%); }
/* 트랙 길이 = 스티키 한 장(100vh) + 장면당 75vh. 장면 수를 마크업의
   data-scenes 로 넘기므로 줄기마다 길이가 저절로 맞는다(넷이면 400vh 로
   전과 같은 값). 좁은 화면은 장면당 65vh(넷이면 360vh). */
.story-track { --scenes: 4; height: calc(100vh + var(--scenes) * 54vh); }
.story-track[data-scenes="5"] { --scenes: 5; }
.story-track[data-scenes="6"] { --scenes: 6; }
.story-track[data-scenes="7"] { --scenes: 7; }
.story-track[data-scenes="8"] { --scenes: 8; }
.story-stage { position: sticky; top: 0; display: grid; grid-template-rows: auto 1fr auto; gap: 18px; height: 100vh; min-height: 560px; padding: 84px 0 26px; overflow: hidden; }

.stage-head { width: min(1180px, calc(100% - 40px)); margin: 0 auto; }
.stage-kicker { margin: 0 0 8px; color: #8174EA; font-size: .74rem; font-weight: 850; letter-spacing: .16em; text-transform: uppercase; }
.stage-head h1 { max-width: 22ch; margin: 0; font-size: clamp(1.9rem, 3.6vw, 3.1rem); line-height: 1.12; letter-spacing: -.055em; background: linear-gradient(112deg, #fff 26%, #d9d4ff 96%); -webkit-background-clip: text; background-clip: text; color: transparent; }

.stage-scene { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1.15fr); align-items: center; gap: 26px; width: min(1180px, calc(100% - 40px)); margin: 0 auto; min-height: 0; }
.stage-canvas { position: absolute; z-index: 0; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.stage-sources, .stage-phone, .stage-say { position: relative; z-index: 1; }

/* 왼쪽 출처 칩 — 1장면에서 하나씩 연동된다 */
.stage-sources { display: flex; flex-direction: column; gap: 10px; align-items: flex-start; margin: 0; padding: 0; list-style: none; justify-self: end; }
.stage-sources li { display: flex; flex-direction: column; gap: 1px; padding: 9px 14px; border: 1px solid var(--line); border-radius: 11px; background: rgba(20,27,47,.86); opacity: .32; transform: translateX(-10px); transition: opacity .45s, transform .45s, border-color .45s; }
.stage-sources li b { font-size: .84rem; font-weight: 850; }
.stage-sources li i { color: var(--muted); font-size: .68rem; font-style: normal; }
/* 칩 수는 줄기마다 다르다(마이디 다섯 · 나머지 넷). 수를 세는 대신 켜진
   칩에만 구동부가 .is-lit 을 단다 — index.html 의 3차원 판 규칙과 짝이다. */
.stage-sources li.is-lit { opacity: 1; transform: none; border-color: rgba(107,92,230,.5); }

/* 가운데 폰 */
.stage-phone { justify-self: center; }
.phone-body { position: relative; width: clamp(240px, 33vh, 320px); aspect-ratio: 196 / 400; padding: 9px; border: 1px solid rgba(255,255,255,.2); border-radius: 30px; background: linear-gradient(168deg, #1B2440, #121A31); box-shadow: 0 26px 60px rgba(3,8,22,.55); }
.phone-notch { position: absolute; left: 50%; top: 13px; width: 52px; height: 5px; border-radius: 99px; background: rgba(255,255,255,.18); transform: translateX(-50%); }
.phone-screen { position: relative; height: 100%; border-radius: 22px; background: #080D1C; overflow: hidden; }

.screen { position: absolute; inset: 0; display: flex; flex-direction: column; gap: 8px; padding: 26px 13px 13px; opacity: 0; transform: translateY(10px); transition: opacity .4s, transform .4s; pointer-events: none; }
/* 장면 수는 줄기마다 다르다(마이디 일곱 · 마이주식 여섯). 그래서
   「몇 번째 화면인가」를 선택자에 박지 않고, 지금 장면인 화면에만 JS 가 .is-now 를
   단다(index.html 끝 카메라 리그). .s1~.sN 은 이제 읽는 사람을 위한 이름일 뿐
   규칙이 걸리지 않는다 — 걸리는 것은 .mall 처럼 내용으로 붙인 이름이다. */
.screen.is-now { opacity: 1; transform: none; }
.screen-cap { margin: 0 0 2px; color: var(--muted); font-size: .62rem; font-weight: 850; letter-spacing: .09em; text-transform: uppercase; }
.screen-points { margin: 2px 0 8px; font-size: 1.7rem; font-weight: 850; letter-spacing: -.05em; }
.screen-points i { margin-left: 2px; color: var(--muted); font-size: .8rem; font-style: normal; font-weight: 800; }
.pay { display: flex; align-items: center; gap: 8px; padding: 11px; border: 1px solid rgba(119,208,167,.4); border-radius: 11px; background: rgba(119,208,167,.1); }
.pay b { font-size: .74rem; }
.pay i { display: block; color: var(--muted); font-size: .62rem; font-style: normal; }

/* 오른쪽 설명 */
.stage-say { max-width: 30ch; }
.say-num { margin: 0 0 10px; font-size: .74rem; font-weight: 850; letter-spacing: .04em; }
.say-num b { color: var(--purple); font-size: 1.5rem; letter-spacing: -.04em; }
.say-num i { margin-left: 5px; color: var(--muted); font-style: normal; }
.say-line { margin: 0 0 8px; font-size: clamp(1.05rem, 1.7vw, 1.5rem); font-weight: 800; line-height: 1.32; letter-spacing: -.04em; }
.say-sub { margin: 0; color: #AEB9CD; font-size: .88rem; line-height: 1.62; }

/* 아래 진행 표시 */
.stage-steps { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; width: min(1180px, calc(100% - 40px)); margin: 0 auto; padding: 0; list-style: none; }
.stage-steps li { display: flex; align-items: center; gap: 7px; padding: 7px 13px; border: 1px solid var(--line); border-radius: 99px; background: rgba(11,16,32,.6); color: var(--muted); font-size: .74rem; transition: color .35s, border-color .35s, background .35s; }
.stage-steps li b { font-size: .68rem; font-weight: 850; letter-spacing: .05em; }
.stage-steps li.is-now { border-color: rgba(107,92,230,.72); background: rgba(107,92,230,.18); color: var(--text); }

.stage-scroll { position: absolute; left: 50%; bottom: 76px; margin: 0; color: var(--muted); font-size: .66rem; letter-spacing: .16em; text-transform: uppercase; transform: translateX(-50%); transition: opacity .4s; }
.story-stage[data-scene="1"] .stage-scroll { animation: stage-bob 1.9s ease-in-out infinite; }
.story-stage:not([data-scene="1"]) .stage-scroll { opacity: 0; }
@keyframes stage-bob { 0%, 100% { transform: translate(-50%, 0); opacity: .85; } 50% { transform: translate(-50%, 5px); opacity: .4; } }

/* === 개인용 두 제품 ==================================================== */
.pick { padding: 96px 0; background: var(--surface); }
/* 섹션 키커 — 무대 키커와 같은 결로. FAQ 처럼 널리 쓰이는 말머리는
   제목 위에 작게 달아 두면 훑는 사람이 이 절이 무엇인지 바로 안다. */
.qa-h { margin-top: 0; }
.pick-h, .qa-h, .biz-h { margin: 0 0 30px; font-size: clamp(1.6rem, 3vw, 2.5rem); letter-spacing: -.06em; }
.pick-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; }
.pick-card { display: flex; flex-direction: column; padding: 30px; border: 1px solid var(--line); border-radius: 20px; background: var(--surface-raised); }
.pick-card.myd { border-color: rgba(107,92,230,.5); background: linear-gradient(152deg, #1A2D55, #2B2660); }
.pick-tag { margin: 0 0 12px; color: #C8C2FF; font-size: .68rem; font-weight: 850; letter-spacing: .1em; text-transform: uppercase; }
/* 2026-10-08 카드 제목(.pick-card h3) — line-height 가 따로 없어 본문 값 1.6 을 물려받았고,
   두세 줄이 되면 30px 글자에 줄 간격이 47px 로 헐거웠다(snpbrain 「묻고, 답과 / 근거를 받습니다」).
   줄 간격만 1.2 로 조이고, 줄어든 만큼을 위아래 안여백(.2em × 2)으로 돌려 한 줄짜리 제목의 자리는 그대로 둔다.
   2026-10-12 760px 묶음 안에 있던 것을 꺼내 폭을 가리지 않는다 — 카드가 두 칸으로 서는 761px 부터도
   제목이 두세 줄로 접히는데(영문 snpvision 1050px 안팎까지 · snpbrain 1215px 안팎까지, 그 가운데
   800px 까지는 석 줄 · 국문 snpbrain 810px 까지) 거기에는 47px 줄 간격이 그대로 남아 있었다.
   한 줄짜리 제목과 그 아래 글은 어느 폭에서도 움직이지 않는다(제목 상자 47.34 → 47.31px). */
.pick-card h3 { margin: 0 0 8px; font-size: 1.85rem; letter-spacing: -.05em; line-height: 1.2; padding-block: .2em; }
.pick-line { margin: 0 0 20px; color: #B8C1D2; font-size: .96rem; line-height: 1.6; }
/* ── 제품 판 안의 목록 ────────────────────────────────────────────────────
   마이디와 마이주식이 같은 틀을 쓴다. 판 키를 맞추는 것이 목적이 아니라,
   둘 다 «첫 물음에 답하는 알맹이» 가 하나씩 필요해서다 —
   마이디는 「어느 여섯 갈래로 모으나」, 마이주식은 「무슨 이야기가 오가나」.
   마지막 줄(.pick-more)은 «여기 더 있다» 는 자리라 테두리를 끊어 그린다. */
.pick-list { display: grid; gap: 8px; margin: 0 0 22px; padding: 0; list-style: none; }
.pick-list li { display: flex; align-items: center; gap: 10px;
  padding: 9px 13px; border: 1px solid rgba(255,255,255,.13); border-radius: 12px;
  background: rgba(255,255,255,.05); color: #E7EAF3; font-size: .86rem; }
.pick-list li b { font-weight: 850; letter-spacing: -.02em; }
.pick-val { margin-left: auto; color: #B8C1D2; text-align: right; }
.pick-more { justify-content: center; border-style: dashed; background: none;
  color: #B8C1D2; font-size: .78rem; }
.pick-facts { display: grid; gap: 9px; margin: 0 0 24px; }
.pick-facts > div { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding-bottom: 9px; border-bottom: 1px solid var(--line); }
.pick-facts dt { color: var(--muted); font-size: .8rem; }
.pick-facts dd { margin: 0; font-size: .94rem; font-weight: 850; letter-spacing: -.02em; }
/* 2026-10-08 이름표와 값이 한 줄에 못 들어가면 둘이 함께 눌려 이름표가 'Good / for' ·
   'My / activity' 로 꺾이고, 두 줄이 된 값은 왼쪽 맞춤이라 값의 세로 줄이 줄마다 달랐다
   (영문 360 · 390). 못 들어가는 줄은 값을 통째로 아랫줄로 내리고, 값은 늘 오른쪽 끝에 맞춘다.
   한 줄에 들어가는 줄(국문은 전부)은 그대로다.
   2026-10-12 760px 묶음 안에 있던 것을 꺼내 폭을 가리지 않는다 — 카드가 두 칸으로 서는
   761~900px 영문(줄 폭 262px)에 같은 탈이 그대로 남아, 'False positives · / missed /
   detections' 석 줄 옆에 값 석 줄이 왼쪽 맞춤으로 섰다. */
.pick-facts > div { flex-wrap: wrap; gap: 2px 12px; }
.pick-facts dd { margin-left: auto; text-align: right; }
.pick-acts { display: flex; flex-wrap: wrap; gap: 10px; margin-top: auto; }

/* === 탭 설명 =========================================================== */
.qa { padding: 96px 0; }
/* 메인에 남긴 길 — FAQ 자체는 문의 페이지에 산다. 같은 내용을 두 곳에 두면
   한쪽만 고쳐지고 조용히 갈라진다. 여기서는 무엇을 답하는지만 알리고 보낸다. */

.tablist { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 18px; }
.tablist button { padding: 11px 18px; border: 1px solid var(--line); border-radius: 99px; background: transparent; color: var(--muted); font-size: .88rem; font-weight: 800; cursor: pointer; transition: .18s; }
.tablist button:hover { border-color: rgba(107,92,230,.5); color: var(--text); }
.tablist button[aria-selected="true"] { border-color: transparent; background: var(--purple); color: #fff; }
/* 휴대폰에서 이름이 긴 탭이 두 줄로 접힐 때 끝 낱말 하나만 떨어졌다 (2026-10-08) —
   fl-studio 영문 둘째 탭이 「What it means that the originals do not / move」.
   두 줄을 고르게 나눈다. 한 줄에 드는 탭은 달라지지 않고, 알약의 꼴도 그대로다. */
@media (max-width: 760px) { .tablist button { text-wrap: balance; } }
.tabpanel { padding: 26px 28px; border: 1px solid var(--line); border-radius: 16px; background: var(--surface); }
.tabpanel p { margin: 0; color: #B8C1D2; font-size: 1rem; line-height: 1.72; }
/* 답은 한 문장이 한 문단. 글자·줄 간격은 건드리지 않고 문장 사이만 벌린다 —
   기본 0.32em 은 줄바꿈으로 읽히지 문단으로는 안 읽힌다. 오른쪽이 비던 것은
   62ch 마개(ch 는 «0» 자 너비라 한글에서는 절반밖에 안 잡는다)를 떼고 그림을
   옆으로 세워 이미 풀었다. */
.tabpanel .ln + .ln { margin-top: .5em; }
/* 그림이 왼쪽, 글이 오른쪽. 그림을 위에 눕히면 그 옆이 통째로 비고 글은
   아래에서 한 줄이 너무 길어진다. 그림 없는 판(27 개)과 신청서 판은 그대로
   두어야 하므로 :has() 로 그림 있는 판만 집는다. */
.tabpanel:not([hidden]):has(> .faq-art) { display: grid; grid-template-columns: minmax(0, 340px) minmax(0, 1fr); gap: 30px; align-items: start; }
.tabpanel > .faq-art { grid-row: 1 / -1; }
.tabpanel:has(> .faq-art) > :not(.faq-art) { grid-column: 2; }
@media (max-width: 760px) {
  .tabpanel:not([hidden]):has(> .faq-art) { grid-template-columns: 1fr; gap: 16px; }
  .tabpanel > .faq-art { grid-row: auto; }
  .tabpanel:has(> .faq-art) > :not(.faq-art) { grid-column: 1; }
}
.tabpanel b { color: var(--text); }

/* === 기업용 한 줄 ====================================================== */
.biz { padding: 96px 0; }   /* 앞의 사이 문장 판(.beat)이 위 여백을 대 주던 때의 0 을 걷는다 — 아래 FAQ 와 같은 값 */
.biz-row { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
.biz-card { display: flex; flex-direction: column; gap: 5px; padding: 20px; border: 1px solid var(--line); border-radius: 14px; background: var(--surface); transition: border-color .18s, transform .18s; }
.biz-card:hover { border-color: rgba(107,92,230,.5); transform: translateY(-2px); }
.biz-card b { font-size: 1rem; letter-spacing: -.03em; }

/* ── 카드 안 그림판 ──────────────────────────────────────────────────
   카드 바닥에 그 제품 페이지가 쓰는 효과를 그대로 깐다. 홈에서 본 움직임이
   눌러서 들어간 페이지에서 다시 맞아 주면, 그 움직임은 장식이 아니라 길 안내다.

   지킨 것 —
   · 바닥(.biz-fx)은 **절대 돌리지 않는다.** 엔진은 화면 좌표(box)와 레이아웃
     좌표(size)를 함께 쓰므로 판이 기울면 만진 자리와 반응하는 자리가 벌어진다.
     기우는 것은 위에 얹힌 선 그림 하나뿐이다.
   · 그림은 포인터를 받지 않는다 — 받으면 카드 밑 캔버스의 pointerdown 이 막혀
     물결이 손을 못 따라온다. 장식이므로 받을 이유도 없다.
   · .biz-art 를 파문(.ink) 위에 올린다. 파문은 카드의 감각이고 그림은 내용이다.
   · 엔진마다 잉크 무게가 크게 다르다(모자이크는 판을 꽉 채우고 비는 거의 비어
     있다). 한 값으로 맞출 수 없어 카드마다 --fx-op 를 따로 준다.               */
.biz-card.has-art { padding-bottom: 0; }
/* 한 줄에 선 카드들의 그림 자리가 서로 어긋났다 (2026-10-12). 같은 줄의 카드는 가장 키 큰 카드에
   맞춰 늘어나는데, 설명이 한 줄인 카드는 그림이 글 바로 밑에 붙은 채 그림 «아래» 로 20px 빈 띠가
   남았다(설명이 두 줄인 카드만 그림이 바닥에 닿았다). 휴대폰 영문에서 FL-STUDIO(390px 까지는
   CataLogix 도)가 두 줄이라 여섯 가운데 넷~다섯이 그랬고, 국문 320px · 영문 768 · 1024px 도 같았다.
   설명 칸이 남는 키를 먹게 해 그림을 늘 카드 바닥에 세운다 — 한 줄의 설명이 모두 같은 줄 수면
   남는 키가 없어 달라지는 것이 없다. */
.biz-card.has-art > b + span { flex: 1 0 auto; }
/* 그림을 담는 통이 <i> 라 그림 속 글자가 기울임을 물려받고 있었다 — 메인의 카드 밑글 여덟 개와
   서비스의 선 그림 꼬리표가 누워 있었다. 일부러 눕힌 흔적은 없다. 바로 세운다 (2026-10-13). */
.biz-art { position: relative; z-index: 2; height: 84px; margin: 14px -20px 0; overflow: hidden; font-style: normal; }
/* [data-fx](918행)가 뒤에서 position:relative 를 주므로 특이도를 한 칸 올려 눌러야
   한다. 그러지 않으면 판이 높이 0 이 되고 fit() 이 실패해 캔버스가 아예 안 산다. */
.biz-art .biz-fx { position: absolute; inset: 0; display: block; opacity: var(--fx-op, .7); transition: opacity .34s var(--settle); }
.biz-card:hover .biz-art .biz-fx, .biz-card:focus-visible .biz-art .biz-fx { opacity: 1; }
.biz-rig { position: absolute; inset: 0; display: block; pointer-events: none;
  transform: rotateX(var(--gx, 0deg)) rotateY(var(--gy, 0deg)); transform-origin: 50% 60%; }
.biz-glyph { width: 100%; height: 100%; pointer-events: none; color: #C8C2FF; opacity: .85; }
.biz-card.is-tilt .biz-rig { will-change: transform; }
.biz-art::after {                      /* 그림이 카드 글자와 붙지 않게 위를 살짝 눕힌다 */
  content: ""; position: absolute; inset: 0 0 auto; height: 22px; pointer-events: none;
  background: linear-gradient(var(--surface), transparent);
}
@media (max-width: 760px) { .biz-art { height: 72px; } }
@media (prefers-reduced-motion: reduce) {
  .biz-rig { transform: none !important; }
  .biz-art .biz-fx { opacity: var(--fx-op, .7) !important; }
}
.biz-card span { color: var(--muted); font-size: .82rem; line-height: 1.5; }
/* 휴대폰 — 작은 카드 글의 끝줄에 낱말 하나만 남았다 (2026-10-12). 카드가 flex 라 이 span 은 블록으로
   서는데, 끝줄 외톨이를 막는 text-wrap: pretty(601행)는 p · li · dd 에만 걸려 여기에 닿지 않았다 —
   영문 odmpass 358~760 '…what is used / where.', fl-studio · index 332~390 '…the next / change',
   국문 odmpass 320~391 「…흐름부터 / 확인합니다.」. 줄 수와 카드 높이는 그대로이고 줄을 나누는 자리만 바뀐다. */
@media (max-width: 760px) { .biz-card > span { text-wrap: pretty; } }

@media (max-width: 1000px) {
  .stage-scene { grid-template-columns: auto minmax(0, 1fr); }
  .stage-sources { display: none; }
  .biz-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 760px) {
  /* 좁은 화면은 장면당 65vh — 넷이면 360vh 로 전과 같은 값이다.
     (트랙 높이를 말하는 규칙은 이 파일에 이 한 줄과 644행 둘뿐이다.
      전에는 여기 420vh, index.html 에 360vh 가 따로 있어 뒤에 오는 쪽이
      조용히 이기고 있었다.) */
  .story-track { height: calc(100vh + var(--scenes) * 47vh); }
  .story-stage { gap: 12px; padding: 72px 0 20px; }
  .stage-scene { grid-template-columns: minmax(0, 1fr); justify-items: center; gap: 16px; }
  .stage-say { max-width: none; text-align: center; }
  .phone-body { width: clamp(230px, 74vw, 310px); }
  .pick-grid { grid-template-columns: minmax(0, 1fr); }
  .pick-card { padding: 24px; }
  /* 카드 제목(.pick-card h3)의 줄 간격 1.2 · 위아래 안여백은 2026-10-12 에 바탕 규칙으로 옮겼다 — 폭을 가리지 않는다. */
  /* 2026-10-08 단추 줄(.pick-acts)이 없는 카드는 표가 맨 끝인데, 표의 아래 여백 24px 가
     카드 안여백 24px 에 얹혀 아래만 48px 로 비었다(위는 24px). 단추 줄이 없으면 뺀다.
     :last-child 로 잡지 않는다 — 누르는 동안 파문(span.ink)이 카드 맨 끝에 붙는다. */
  .pick-card:not(:has(> .pick-acts)) > .pick-facts { margin-bottom: 0; }
  /* 2026-10-08 카드 머리 라벨(.pick-tag) — .68rem(10.9px)은 휴대폰에서 읽기에 작았다.
     판 말머리(.kicker 12.2px)에 가까운 12px 로 올린다. 가장 긴 영문 라벨도 한 줄에 든다. */
  .pick-tag { font-size: .75rem; }
  /* 같은 판의 목록(.pick-list)도 이름이 눌려 'Check- / in' 으로 꺾였다. 이름은 줄이지 않는다.
     2026-10-12 값 글(.pick-val)이 뒤따르는 줄에만 건다 — 값 글은 접힐 수 있지만 마이주식 줄의
     칩과 댓글 아이콘은 줄지 못한다. 영문 320px 에서 'Samsung Electronics' 가 접히지 못해
     아이콘이 알약 밖으로 12.5px 밀려 나갔다. 마이주식 줄의 이름은 전처럼 접힌다. */
  .pick-list li b:has(+ .pick-val) { flex: none; }
  .pick { padding: 68px 0; }
  .qa { padding: 68px 0; }
  .biz { padding: 68px 0; }
  /* 「스크롤 · 드래그」 안내는 좁은 화면에서 감춘다. bottom 값을 66 → 28 → 12 로
     내려 가며 맞춰 봤지만 무대마다 제목 높이가 달라 한 값으로 다 맞출 수가
     없다 — 영문 390 에서 마이디 +27 · 마이주식 +15 였고, 설명 덩이가 긴 무대는
     안내 자리까지 내려오는데 더 내리면 판 밖으로 나가고, 흐름에 넣어도
     .stage-say 가 붙박이라 소용이 없다.
     이 안내는 «드래그» 가 낯선 데스크톱에서 값을 한다. 손가락으로 미는 화면에서는
     굳이 없어도 되고, aria-hidden 인 장식이라 낭독기에는 원래부터 안 읽힌다.
     움직임부터 끄는 까닭 — 803행 @keyframes stage-bob 이 opacity 를 .85↔.4 로
     몰고 있어 그냥 opacity:0 만 적으면 진다.
     display:none 이 아닌 까닭 — 지우면 index.html 521행 stage-fx 의 data-clear 가
     가리키는 자리가 사라진다. */
  .stage-scroll,
  .story-stage[data-scene="1"] .stage-scroll { animation: none; opacity: 0; }
  /* 눈에서만 줄인다 — display:none 은 접근성 트리에서도 지워서, 휴대폰
     낭독기에는 「01 02 … 07」 숫자만 남고 그 걸음이 무엇인지 알 길이 없었다. */
  .stage-steps li span { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
}

/* 평소엔 오른쪽 .stage-say 가 설명을 맡으므로 카드 안 설명은 숨겨 둔다. */
.screen-say { display: none; }

/* 움직임을 원치 않으면 무대를 붙이지 않는다. 폰 한 대에 네 장면을 쌓는 대신
   걸음을 나란히 편 스토리보드로 바꾼다 — 스크롤 없이도 흐름이 한눈에
   읽히고, 각 걸음이 자기 설명을 달고 선다. 걸음 수는 줄기마다 다르다
   (마이디 일곱 · 마이주식 여섯).                                        */
@media (prefers-reduced-motion: reduce) {
  .story-track { height: auto; }
  .story-stage { position: static; display: block; height: auto; min-height: 0; padding: 84px 0 40px; overflow: visible; }
  .stage-scroll, .stage-sources, .stage-say, .stage-canvas { display: none; }

  .stage-scene { display: block; }
  .stage-phone { justify-self: stretch; }
  /* !important 가 붙은 까닭 — 아래(945행 넉 겹 그림자 · 1452행 폰 폭)에 같은
     선택자가 «더 뒤» 에 있어 무게가 같으면 그쪽이 이긴다. 미디어쿼리는 무게를
     더하지 않는다. 재어 보니 그림자와 폭이 둘 다 되살아났다(2026-09-28). */
  .story-stage .phone-body { width: 100%; aspect-ratio: auto; padding: 0; border: 0; border-radius: 0; background: none; box-shadow: none !important; }
  /* 아래 「.story-stage .phone-body」(0,2,0)가 위 한 줄(0,1,0)의 width 를 이겨,
     펴려던 격자가 320px 통에 갇혀 있었다. 같은 무게로 올려 되찾는다. */
  .story-stage .phone-body { width: 100% !important; }
  .story-stage .phone-notch { display: none; }
  /* 폰을 판 너비에 «못 박는다». 화면(.screen)이 크기 컨테이너라 제 안의
     넓이를 바깥에 알리지 않는데, .stage-phone 은 절대 자리라 제 속으로
     폭을 정한다 — 그래서 가두는 순간 폰이 107px 로 주저앉았다. 여기서는
     스토리보드라 정상 흐름으로 되돌리고 판 너비를 그대로 받는다. */
  .stage-phone { position: static; width: 100%; transform: none; }
  /* 칸 수는 걸음 수가 정한다 — 트랙 길이와 같은 손잡이(data-scenes)를 쓴다.
     넷이면 전과 같은 두 칸, 여섯·일곱이면 세 칸이다. auto-fill 로 두었더니
     자리 넓이만 보고 넷이든 일곱이든 늘 네 칸을 만들었다. */
  .story-stage .phone-screen { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; height: auto; border-radius: 0; background: none; }
  .story-track[data-scenes="6"] .phone-screen,
  .story-track[data-scenes="7"] .phone-screen,
  .story-track[data-scenes="8"] .phone-screen { grid-template-columns: repeat(3, minmax(0, 1fr)); }

  /* 바탕을 밝게 — 1041행이 이 .screen 의 글자를 #1A1D29 로 칠하는데 여기서
     어둡게 깔면 어두운 글자가 어두운 카드에 묻힌다. 실제 마이디 화면도
     밝은 카드다. index.html 이 인라인으로 같은 손질을 해 두었었다. */
  /* 크기 가둠을 «반드시» 푼다 — 여기서 .screen 은 position:static 에 높이가
     auto 다. container-type:size 를 그대로 두면 가둠이 높이를 0 으로 만들어
     스토리보드 카드가 통째로 빈칸이 된다. 카드는 잘리지 않으므로 「반쯤 걸친
     것 감추기」 규칙도 여기서는 필요 없다. */
  .story-stage .screen { position: static; container-type: inline-size; gap: 9px; padding: 22px; border: 1px solid rgba(0,0,0,.08); border-radius: 16px; background: #F5F6FA; opacity: 1; transform: none; }
  .story-stage .screen-say { display: block; margin: 12px 0 0; padding-top: 12px; border-top: 1px solid var(--line); color: #AEB9CD; font-size: .82rem; line-height: 1.6; }
  .story-stage .screen-say b { display: block; margin-bottom: 4px; color: var(--purple); font-size: .68rem; font-weight: 850; letter-spacing: .08em; }

  .stage-steps { margin-top: 26px; }
  .stage-steps li { border-color: rgba(107,92,230,.4); background: rgba(107,92,230,.1); color: var(--text); }
}
@media (prefers-reduced-motion: reduce) and (max-width: 700px) {
  .story-stage .phone-screen { grid-template-columns: minmax(0, 1fr); }
}

/* === 터치감 ============================================================
   누르면 눌리고, 닿은 자리에 파문이 남고, 손끝 쪽으로 아주 살짝 끌려온다.
   전환은 스프링 곡선(cubic-bezier 의 뒤끝이 1 을 넘김)이라 제자리에 서기 전에
   한 번 살짝 넘어간다 — 선형 이징에는 없는 감각이다.                     */
:root {
  /* 가볍게 넘겼다 돌아오는 이징 — index.html 인라인에만 있어서 다른 장에서 쓰면
     조용히 무시됐다. 전역으로 올린다(인라인 쪽은 같은 값이라 부딪히지 않는다). */
  --pop: cubic-bezier(.18, 1.62, .38, 1);
  --spring: cubic-bezier(.22, 1.4, .36, 1);
  --settle: cubic-bezier(.2, .9, .3, 1);
}

/* 눌린 상태 */
.btn, .biz-card, .pick-card, .tablist button, .stage-steps li, .mobile-beta {
  transition: transform .34s var(--spring), border-color .2s, background .2s, box-shadow .28s var(--settle);
  /* will-change 는 **움직이는 동안만** 건다. 여섯 카드가 늘 합성 레이어로 떠 있으면
     저사양 기기에서 메모리만 먹는다. 눌리거나 도는 순간에만 켠다. */
}
.is-pressed { transform: scale(.955) !important; transition-duration: .09s !important; }
.pick-card.is-pressed, .biz-card.is-pressed { transform: scale(.985) !important; }
.btn.is-pressed, .biz-card.is-pressed, .pick-card.is-pressed, .tablist button.is-pressed,
.stage-steps li.is-pressed, .mobile-beta.is-pressed { will-change: transform; }
@media (hover: hover) and (pointer: fine) {
  .btn:hover, .biz-card:hover, .pick-card:hover, .tablist button:hover { will-change: transform; }
}
.screen.is-pressed { transform: scale(.99) !important; }

/* 닿은 자리에서 퍼지는 파문 */
.ink {
  position: absolute; z-index: 0; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle, rgba(200,194,255,.42) 0%, rgba(200,194,255,.14) 45%, transparent 70%);
  animation: ink-spread .58s var(--settle) forwards;
}
.btn.primary .ink, .mobile-beta .ink, .tablist button[aria-selected="true"] .ink {
  background: radial-gradient(circle, rgba(255,255,255,.5) 0%, rgba(255,255,255,.16) 45%, transparent 70%);
}
@keyframes ink-spread { from { transform: scale(0); opacity: 1; } to { transform: scale(1); opacity: 0; } }

/* 파문이 카드 모서리 밖으로 새지 않게 */
.btn, .biz-card, .pick-card, .tablist button, .stage-steps li, .mobile-beta, .screen { overflow: hidden; }
/* 버튼 안 글자는 파문 위에 */
/* :not(.sr-only) 를 붙인 까닭 — 이 규칙이 (0,1,1) 로 .sr-only(0,1,0) 의
   position:absolute 를 이겨, 숨은 글자가 흐름 안으로 들어와 단추 오른쪽에
   1px + gap 8px 을 더하고 있었다(단추 열셋). 숨은 글자는 비켜 준다. */
.btn > *:not(.sr-only), .tablist button > *:not(.sr-only), .biz-card > *:not(.sr-only),
.pick-card > *:not(.sr-only), .screen > *:not(.sr-only) { position: relative; z-index: 1; }

/* 단추는 모두 손끝 쪽으로 끌려온다. 전에는 1차 행동(.btn.primary)만 그랬고
   테두리만 있는 짝은 :hover 로 2px 떠올랐다 — 나란히 선 둘이 서로 다르게
   움직여, 같은 줄의 단추인데 다른 물건처럼 보였다(2026-09-23). */
.btn { transform: translate(var(--mx, 0), var(--my, 0)); }
.btn.is-pressed { transform: translate(var(--mx, 0), var(--my, 0)) scale(.955) !important; }

/* 폰이 손끝 쪽으로 기운다 */
.stage-scene { perspective: 1100px; }
.stage-phone { transform-style: preserve-3d; }
.phone-body {
  transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  transition: box-shadow .3s var(--settle);
}
.story-stage.is-scrub { cursor: grabbing; user-select: none; }
.stage-phone { cursor: grab; }

/* ── 폰을 판에서 띄운다 ── 뒤로 빛 한 켜, 아래로 그림자 한 켜 ──────────────
   참고한 판들(크라켄 · moto-card · kott)은 하나같이 물건을 «바닥 위에 띄워»
   둔다. 테두리를 더 그리는 대신 뒤와 아래에 깊이를 깐다. preserve-3d 안에서는
   z-index 가 아니라 Z 가 앞뒤를 정하므로 translateZ 로 뒤로 보낸다. */
.svc-stage-phone { position: relative; }
.stage-phone, .svc-stage-phone { transform-style: preserve-3d; }
.stage-phone::before, .svc-stage-phone::before {      /* 뒤에서 번지는 빛 */
  content: ""; position: absolute; left: 50%; top: 47%;
  width: 134%; aspect-ratio: 1 / 1.04; border-radius: 50%;
  background: radial-gradient(closest-side, rgba(107,92,230,.30), rgba(107,92,230,.09) 55%, transparent 76%);
  transform: translate(-50%, -50%) translateZ(-70px);
  filter: blur(24px); pointer-events: none;
}
.stage-phone::after, .svc-stage-phone::after {        /* 바닥에 닿는 그림자 */
  content: ""; position: absolute; left: 50%; bottom: -20px;
  width: 72%; height: 28px; border-radius: 50%;
  background: radial-gradient(closest-side, rgba(3,8,22,.82), rgba(3,8,22,.3) 60%, transparent 80%);
  transform: translateX(-50%) translateZ(-46px);
  filter: blur(10px); pointer-events: none;
}
/* 그림자는 한 겹이 아니라 넷이다 — 닿는 자리 · 가까이 · 멀리 · 아주 멀리.
   한 겹짜리(0 26px 60px)는 «붙여 놓은 그림» 으로 보였다. */
.phone-body {
  box-shadow: 0 2px 5px rgba(3,8,22,.42), 0 14px 28px rgba(3,8,22,.42),
              0 38px 74px rgba(3,8,22,.52), 0 72px 132px rgba(9,6,40,.40);
}
.story-stage.is-scrub .phone-body {
  box-shadow: 0 3px 7px rgba(3,8,22,.5), 0 18px 34px rgba(3,8,22,.5),
              0 46px 86px rgba(3,8,22,.62), 0 84px 150px rgba(9,6,40,.5);
}

/* 무대를 끌 수 있다는 표시 — 첫 장면에서만 */
.stage-scroll::after {
  content: " · 끌어서 넘기기";
  opacity: .55;
}

/* 영문일 때는 같은 자리에 영문으로. `:lang(en)` 은 <html lang="en"> 하나로
   판가름하므로, 토글로 넘기는 프로토타입에서도(토글이 lang 도 함께 바꾼다)
   국문·영문이 다른 파일인 라이브 판에서도 같이 걸린다. */
.stage-scroll:lang(en)::after {
  content: " · drag to advance";
}

@media (hover: none) {
  /* 손가락에는 자석·기울기가 없다. 대신 누르는 감각만 남긴다. */
  .btn { transform: none; }
  .btn.is-pressed { transform: scale(.955) !important; }
  .stage-phone { cursor: auto; }
}

@media (prefers-reduced-motion: reduce) {
  .btn, .biz-card, .pick-card, .tablist button, .stage-steps li, .mobile-beta { transition: border-color .2s, background .2s; will-change: auto; }
  .is-pressed { transform: none !important; }
  .ink { display: none; }
  .phone-body { transform: none; }
  .stage-phone { cursor: auto; }
  .stage-phone::before, .stage-phone::after { display: none; }
  .stage-scroll::after { content: ""; }
}

/* === 인터랙션 효과 판 ==================================================== */
[data-fx] { position: relative; isolation: isolate; }
.fx-canvas { position: absolute; z-index: 0; inset: 0; width: 100%; height: 100%; pointer-events: none; }
[data-fx] > *:not(.fx-canvas) { position: relative; z-index: 1; }
[data-jitter] { cursor: grab; }
[data-jitter]:active { cursor: grabbing; }

/* === 토스·케이뱅크에서 가져온 것 ========================================
   ① 스크롤에 맞춰 한 줄씩 올라온다.
   ② 카드에는 동그란 화살표 하나 — 누를 수 있다는 표시.
   ③ 좁은 화면에서 카드 줄은 손가락으로 밀어 넘긴다(케이뱅크 카루셀).

   「한 화면에 한 문장」 대목(.beat · .chipline)은 걷었다 — 사이 문장 판을
   인덱스 셋, 서비스 하나 모두 지우면서 쓰는 곳이 사라졌다.   */

/* ① 스크롤에 맞춰 올라오며 등장 */
.reveal { opacity: 0; transform: translateY(20px); transition: opacity .62s var(--settle), transform .62s var(--settle); transition-delay: calc(var(--i, 0) * .075s); }
.reveal.is-in { opacity: 1; transform: none; }

/* ② 카드의 동그란 화살표 */
.pick-card { position: relative; }
.go {
  position: absolute; right: 26px; top: 26px;
  display: grid; place-items: center; width: 38px; height: 38px;
  border: 1px solid var(--line-strong); border-radius: 50%;
  color: var(--muted); font-size: 1rem;
  transition: transform .34s var(--spring), background .22s, color .22s, border-color .22s;
}
.pick-card:hover .go, .pick-card:focus-within .go { transform: translateX(4px); border-color: transparent; background: var(--purple); color: #fff; }

/* ③ 좁은 화면에서 카드 줄은 밀어서 넘긴다 */
@media (max-width: 760px) {
  .go { right: 20px; top: 20px; width: 33px; height: 33px; }
  [data-rail] {
    display: flex; gap: 12px;
    margin-inline: calc(-1 * var(--gutter, 20px));
    padding: 2px var(--gutter, 20px) 14px;
    overflow-x: auto; scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch; scrollbar-width: none;
    /* 2026-10-08 스냅(mandatory)이 왼쪽 안여백을 삼켜 첫 카드가 글줄(30px)보다 16px 왼쪽에
       서 있었다 — 손대기 전부터 scrollLeft 가 16. 스냅 자리를 안여백만큼 들여 준다. */
    scroll-padding-inline: var(--gutter, 20px);
  }
  [data-rail]::-webkit-scrollbar { display: none; }
  [data-rail] > * { flex: 0 0 min(76vw, 300px); scroll-snap-align: start; }
  /* 2026-10-08 첫 카드를 제자리(30px)에 세우면 둘째 카드는 오른쪽 끝에 30~38px(11~13%)만 걸친다.
     등장 관찰자(.reveal)의 문턱이 15% 라, 카드마다 .reveal 을 단 줄(odmpass)에서는 둘째 카드가
     투명한 채로 남아 「옆에 더 있다」는 단서가 사라진다. 첫 카드만 올라오게 하고 나머지는 처음부터 보이게 둔다. */
  [data-rail] > .reveal:not(:first-child) { opacity: 1; transform: none; }
  /* 레일 점 — 여섯 중 지금 몇째인지. 좁은 화면에서만 뜬다. */
  .rail-dots { display: flex; gap: 7px; justify-content: center; margin: 2px 0 0; }
  .rail-dots i { width: 6px; height: 6px; border-radius: 50%; background: rgba(139,149,168,.34);
    transition: background .2s, transform .2s var(--settle); }
  .rail-dots i.on { background: var(--purple); transform: scale(1.45); }
}

@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
  .go { transition: none; }
  .pick-card:hover .go { transform: none; }
}

/* === 제품 페이지에서 온 보탬 ============================================ */

/* 효과 캔버스가 붙은 판은 절대 scale() 을 태우지 않는다.
   getBoundingClientRect(화면 좌표)와 stage.size(레이아웃 좌표)가 어긋나면
   만진 자리와 반응하는 자리가 벌어진다. */
.hero-art[data-fx] { transform: none; min-height: 300px; }
@media (max-width: 760px) { .hero-art[data-fx] { min-height: 260px; transform: none; } }

/* 잡으면 떠는 판은 transform 전환을 타지 않는다 — 프레임마다 바뀌는 떨림이
   0.34s 스프링에 뭉개져 흐물거린다. 색 전환만 남긴다. */
[data-jitter] { transition: border-color .2s, background .2s !important; }

/* 스포트라이트가 유일한 광원이 되도록 그 히어로만 방을 어둡게 한다. */

/* 섹션 두 장이 바로 이어질 때 위 여백만 지운다. */
.section.section-tight { padding-top: 0; }

/* === 폰 화면 — 실제 마이디 앱 대시보드 ==================================
   Google Play 공개 스크린샷을 근거로 실물 구조를 옮겼다. 실제 앱은 밝은 파랑에
   흰 카드라 어두운 페이지 위에서 진짜 화면처럼 도드라진다.
   담은 것 — 상단 포인트 잔액 · 출석 배너(0/5) · 퀵아이콘 · 참여 가능 혜택
   (건별 포인트) · 포인트몰(상품 31개 · 브랜드 6곳 · 네이버페이 5,000P).            */
.phone-screen { background: #F5F6FA; }
.screen { gap: 7px; padding: 24px 10px 15px; color: #1A1D29; }

.app-bar { display: flex; align-items: center; justify-content: space-between; gap: 2.632cqw; }
.app-logo { color: #2B4BF2; font-size: 5.754cqw; font-weight: 900; letter-spacing: -.04em; }
.app-pt { padding: 1.316cqw 3.509cqw; border-radius: 99px; background: #EEF1FF; color: #2B4BF2; font-size: 4.211cqw; font-weight: 850; }
.app-pt b { font-weight: 850; }

/* 퀵메뉴 아이콘 — 이모지를 쓰면 기기마다 다른 그림이 뜨고, 무엇보다 실제 앱
   화면이 아니라 급조한 시늉으로 읽힌다. 15px 로 줄어드는 자리라 획을 굵게 잡고
   잔재주를 뺐다. 색은 앱의 파랑을 그대로 쓴다. */
.icons { position: absolute; width: 0; height: 0; overflow: hidden; }

.screen .screen-cap { margin: 0.877cqw 0 0; color: #6B7080; font-size: 4.070cqw; font-weight: 850; letter-spacing: .02em; text-transform: none; }

.app-rows { display: flex; flex-direction: column; gap: 1.754cqw; margin: 0; padding: 0; list-style: none; }
.app-rows li { display: flex; align-items: center; justify-content: space-between; gap: 2.632cqw; padding: 3.070cqw 3.947cqw; border-radius: 3.947cqw; background: #fff; font-size: 4.000cqw; }
.app-rows li > span { display: flex; align-items: center; gap: 2.193cqw; color: #1A1D29; font-weight: 700; }
.app-rows b { color: #2B4BF2; font-size: 3.860cqw; font-weight: 850; }

.app-foot { margin: auto 0 0; color: #686F84; font-size: 3.719cqw; text-align: center; }

/* ── 그린 화면에도 기기 줄을 단다 ───────────────────────────────────
   사진 화면(.screen.shot)에는 상태 줄(시각 · 신호 · LTE · 배터리)과 홈 막대가
   사진 안에 이미 찍혀 있습니다. 그린 화면에는 그것이 없어서, 같은 폰 안인데도
   한쪽은 진짜 앱처럼, 다른 한쪽은 흰 종이처럼 보였습니다.

   사진(app/app-points.webp, 1125x2436)을 재어 같은 꼴로 그립니다 —
     띠 높이   150 / 2436 = 6.2%      왼 여백   72 / 1125 = 6.4%
     오른 여백  60 / 1125 = 5.3%      오른 무리 x 840~1068 = 폭의 20.3%
     노란 알약 82x41 · #FED600 · 글자는 어둡다
   시각도 사진과 같은 16:32 입니다.

   오른쪽 무리는 글이 둘(LTE · 100)이라 content 한 줄로는 못 그립니다. 그림
   파일을 새로 두지 않으려고 SVG 를 배경으로 박습니다 — 폰이 커지면 함께
   늘어나고, 색은 여기 한 곳에서만 고치면 됩니다. */
.screen { container-type: size; }
/* 띠가 첫 칸으로 서므로 위 여백은 띠에게 넘긴다. --sx 는 화면의 옆 여백이고,
   띠가 그만큼 되물려 가장자리까지 닿는다 — 한 곳에서만 고치면 된다. */
.screen:not(.shot) { --sx: 10px; padding-top: 0; }
.screen:not(.shot)::before {
  content: "16:32";
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  height: 12.5cqw;
  margin: 0 calc(-1 * var(--sx)) 1.754cqw;
  padding: 0 5.7cqw 0 6.85cqw;
  color: #151827;
  font-size: 4.4cqw;
  font-weight: 850;
  letter-spacing: .01em;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 60 12'%3E%3Crect x='0' y='6.5' width='1.7' height='4.5' rx='.5' fill='%23151827'/%3E%3Crect x='2.6' y='4.5' width='1.7' height='6.5' rx='.5' fill='%23151827'/%3E%3Crect x='5.2' y='2.5' width='1.7' height='8.5' rx='.5' fill='%23151827'/%3E%3Crect x='7.8' y='0.5' width='1.7' height='10.5' rx='.5' fill='%23151827'/%3E%3Ctext x='12.4' y='9.6' font-family='sans-serif' font-size='8.4' font-weight='700' fill='%23151827'%3ELTE%3C/text%3E%3Crect x='31.6' y='.4' width='20.4' height='11.2' rx='5.6' fill='%23FED600'/%3E%3Ctext x='41.8' y='9.2' font-family='sans-serif' font-size='7.6' font-weight='800' fill='%23151827' text-anchor='middle'%3E100%3C/text%3E%3C/svg%3E") no-repeat right 5.7cqw center / 21.7cqw 4.4cqw;
  pointer-events: none;
}

/* 홈 막대 — 사진 화면 맨 아래의 그 짧은 선입니다. */
.screen:not(.shot)::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 6px;
  z-index: 2;
  width: 34%;
  height: 3px;
  border-radius: 99px;
  background: rgba(26, 29, 41, .22);
  transform: translateX(-50%);
  pointer-events: none;
}

/* 움직임을 줄인 화면에서는 폰 모형이 없어지고 화면이 격자 칸으로 눕습니다.
   그때는 기기 줄이 뜻을 잃으므로 함께 걷습니다. */
@media (prefers-reduced-motion: reduce) {
  .story-stage .screen:not(.shot)::before,
  .story-stage .screen:not(.shot)::after { display: none; }
}

.app-tabs { display: flex; gap: 3.509cqw; padding-bottom: 2.193cqw; border-bottom: 1px solid #E4E7F0; }
.app-tabs i { color: #686F84; font-size: 3.930cqw; font-style: normal; font-weight: 800; }
.app-tabs i.on { color: #1A1D29; border-bottom: 2px solid #2B4BF2; padding-bottom: 1.316cqw; }

/* 정지 화면(스토리보드)에서는 밝은 카드 위에 설명이 얹히므로 글자색을 뒤집는다. */
.screen-say { color: #4A4F63; border-top-color: #E4E7F0; }
.screen-say b { color: #2B4BF2; }

/* 무대 배경 — 히어로와 같은 인공신경망. 장면이 바뀌어도 이 결은 그대로 간다. */
.story > .neural-canvas { position: absolute; z-index: 0; inset: 0; width: 100%; height: 100%; opacity: .26; pointer-events: none; }
.story-track { position: relative; z-index: 1; }

/* 폰 모형 안에서 메인과 서비스 탭이 함께 쓰는 칸 셋 ─────────────────────
   (전에는 index.html 의 flow-css 에만 있어, 서비스 탭에 같은 화면을 세우니
    규칙이 안 걸려 글자가 통째로 커졌습니다.) */
/* 줄 안에 붙는 매수/매도 알약. 색으로만 가르지 않고 글자를 함께 둔다
   (기획서 12절의 30~50대 사용성 규칙과 같은 까닭이다). */
.app-rows li span em, .ap-head em { display:inline-block; margin-left:5px; padding:1px 2.193cqw; border-radius:2.193cqw;
  background:#EEF1FB; color:#4A4F63; font-size:3.088cqw; font-style:normal; font-weight:850; vertical-align:middle; }
/* 매수는 붉게, 매도는 푸르게 — 마이주식 브랜드 보드의 시세 색이다. 보드에
   「절대 반대로 쓰지 않는다」 고 적혀 있다(#F0454B · #2E7CF6). 7px 글씨라
   옅은 바탕에서 4.5:1 을 넘기도록 잉크만 한 단 내려 쓴다. */
.app-rows li span em.buy, .ap-head em.buy { background:#FDE7E8; color:#C22930; }
.app-rows li span em.sell, .ap-head em.sell { background:#E4EEFD; color:#1C5CC4; }
/* ── 마이주식 폰 화면 다섯 ─────────────────────────────────────────────
   2026-09-30 에 실제 앱 화면(출시판)을 보고 다시 지었습니다. 그 전까지는
   「종목 A~D」로 세운 시안이었고 화면마다 「시안」 꼬리표를 달고 있었습니다.
   글씨는 .app-rows 와 같은 눈금(.55~.6rem)을 씁니다 — 폰이 240~320px 이라
   한 단만 키워도 칸이 넘칩니다. */

/* 머리줄의 곁글 — 「로그인」 「취소」 「등록」 「‹」 처럼 양옆에 앉는 것 */
.app-side { color: #2B4BF2; font-size: 3.860cqw; font-style: normal; font-weight: 800; }
.app-side.mute { color: #9AA0B0; }
.app-back { color: #4A4F63; font-size: 5.053cqw; font-style: normal; font-weight: 700; line-height: 1; }
.app-title { flex: 1; color: #1A1D29; font-size: 4.351cqw; font-weight: 850; letter-spacing: -.02em; text-align: center; }

/* 검색칸 — 돋보기는 글자가 아니라 배경으로 그린다(글꼴이 늦게 와도 안 흔들린다) */
.app-seek {
  margin: 0; padding: 3.070cqw 3.947cqw 3.070cqw 9.649cqw; border-radius: 3.947cqw;
  background: #F1F3F7 url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%239AA0B0' stroke-width='1.8'%3E%3Ccircle cx='7' cy='7' r='4.6'/%3E%3Cpath d='M10.6 10.6 14 14' stroke-linecap='round'/%3E%3C/svg%3E") no-repeat 3.509cqw center / 3.947cqw 3.947cqw;
  color: #9AA0B0; font-size: 3.860cqw; font-weight: 600;
}

/* 글 목록 — 종목 알약 · 금액 · 본문 · 글쓴이 · 댓글 수 */
.app-posts { display: flex; flex-direction: column; gap: 2.193cqw; margin: 0; padding: 0; list-style: none;
  flex: 1 1 auto; min-height: 0; overflow: hidden; }
.app-posts li { padding: 3.509cqw 3.947cqw; border-radius: 4.386cqw; background: #fff; }
.ap-head { display: flex; align-items: center; gap: 0; }
.ap-head { white-space: nowrap; }
.ap-head b { padding: 0.877cqw 2.632cqw; border-radius: 2.632cqw; background: #F1F3F7; color: #1A1D29; font-size: 3.860cqw; font-weight: 850; overflow: hidden; text-overflow: ellipsis; }
.ap-head i { margin-left: auto; color: #6B7080; font-size: 3.860cqw; font-style: normal; font-weight: 800; }
.ap-head em + i { font-size: 3.509cqw; font-weight: 700; color: #9AA0B0; }
.ap-body { margin: 2.193cqw 0 0; color: #1A1D29; font-size: 3.860cqw; font-weight: 600; line-height: 1.5;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.ap-body.full { -webkit-line-clamp: 3; }
.ap-meta { display: flex; align-items: center; margin-top: 2.193cqw; color: #9AA0B0; font-size: 3.509cqw; font-weight: 700; white-space: nowrap; overflow: hidden; }
.ap-meta i { margin-left: auto; font-style: normal; }

/* 로그인 권유 — 미리보기 세 건을 다 읽으면 여기서 막힌다 */
.app-gate { margin: auto 0 0; padding-top: 3.509cqw; border-top: 1px solid #E4E7F0; text-align: center; }
/* 여기서 멈춘다는 말은 회색 한 줄로는 안 들린다 — 단추 위의 주석처럼
   읽혔다. 자물쇠 한 자를 앞에 세우고 잉크를 올리고 위로 선을 그어
   «미리보기는 여기까지» 를 눈으로 보이게 한다. */
.app-gate span { display: flex; align-items: center; justify-content: center; gap: 1.754cqw;
  margin-bottom: 3.070cqw; color: #434A5E; font-size: 4.000cqw; font-weight: 800; letter-spacing: -.02em; }
.app-gate span::before {
  content: ""; flex: 0 0 auto; width: 3.509cqw; height: 3.509cqw;
  background: #4F55F0; mask: no-repeat center / contain; -webkit-mask: no-repeat center / contain;
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23000' d='M8 1a3.6 3.6 0 0 0-3.6 3.6V6H4a1.4 1.4 0 0 0-1.4 1.4v6A1.4 1.4 0 0 0 4 14.8h8a1.4 1.4 0 0 0 1.4-1.4v-6A1.4 1.4 0 0 0 12 6h-.4V4.6A3.6 3.6 0 0 0 8 1Zm0 1.8a1.8 1.8 0 0 1 1.8 1.8V6H6.2V4.6A1.8 1.8 0 0 1 8 2.8Z'/%3E%3C/svg%3E");
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23000' d='M8 1a3.6 3.6 0 0 0-3.6 3.6V6H4a1.4 1.4 0 0 0-1.4 1.4v6A1.4 1.4 0 0 0 4 14.8h8a1.4 1.4 0 0 0 1.4-1.4v-6A1.4 1.4 0 0 0 12 6h-.4V4.6A3.6 3.6 0 0 0 8 1Zm0 1.8a1.8 1.8 0 0 1 1.8 1.8V6H6.2V4.6A1.8 1.8 0 0 1 8 2.8Z'/%3E%3C/svg%3E");
}
.app-gate b { display: block; padding: 4.386cqw 0; border-radius: 4.386cqw; background: #4F55F0; color: #fff;
  font-size: 4.421cqw; font-weight: 900; letter-spacing: -.02em;
  box-shadow: 0 1.754cqw 4.386cqw rgba(79, 85, 240, .28); }

/* 간편 로그인 — 넉 줄이 저마다 제 브랜드 색이다 */
.app-oauth { display: flex; flex-direction: column; gap: 2.193cqw; margin: 0; padding: 0; list-style: none; }
.app-oauth li { padding: 3.070cqw 0; border-radius: 3.947cqw; font-size: 3.930cqw; font-weight: 850; text-align: center; }
.oa-kakao { background: #FEE500; color: #191600; }
.oa-naver { background: #03C75A; color: #fff; }
.oa-apple { background: #111; color: #fff; }
.oa-google { background: #F1F3F7; color: #1A1D29; }
.app-lead { margin: 0; color: #6B7080; font-size: 3.719cqw; font-weight: 700; line-height: 1.5; text-align: center; white-space: pre-line;
  min-height: 0; overflow: hidden; }   /* 폰이 아주 작아지면 안내글이 먼저 접힌다 — 로그인 넉 줄은 지킨다 */
.app-lead b { display: block; margin-bottom: 1.316cqw; color: #1A1D29; font-size: 4.772cqw; font-weight: 900; letter-spacing: -.02em; }

/* 바텀시트 — 실제 화면은 목록 위로 «아래에서» 올라온다.
   margin-top:auto 로 바닥에 붙이면, 폰이 작아질 때 위의 흐린 목록이 먼저 줄고
   시트는 제 키를 지킨다(로그인 넉 줄이 잘리면 안 된다). */
.app-dim { opacity: .34; }
.app-sheet { display: flex; flex-direction: column; gap: 2.632cqw; margin: auto -10px -15px;
  padding: 3.070cqw 5.263cqw 5.263cqw; border-radius: 6.140cqw 6.140cqw 0 0; background: #fff;
  box-shadow: 0 -10px 24px rgba(20, 24, 42, .10);
  /* 창이 아주 낮아 폰이 250px 가 되면 시트도 눌린다 — 안내글(.app-lead)이 먼저
     접히고 로그인 넉 줄이 끝까지 남는다. min-height:0 이 없으면 아이들의
     min-content 키가 바닥이 되어 시트가 폰 밖으로 밀려난다. */
  min-height: 0; }
.app-grab { align-self: center; width: 12.281cqw; height: 1.316cqw; border-radius: 99px; background: #D7DAE3; }

/* 글쓰기 — 이름표 · 필수 표 · 입력칸 */
.app-form { display: flex; flex-direction: column; gap: 3.070cqw; margin: 0; padding: 0; list-style: none;
  min-height: 0; overflow: hidden; }
.af-label { display: flex; align-items: center; gap: 1.754cqw; color: #1A1D29; font-size: 3.860cqw; font-weight: 850; }
.af-label em { padding: 1px 2.193cqw; border-radius: 2.193cqw; background: #EEF1FF; color: #4F55F0; font-size: 3.088cqw; font-style: normal; font-weight: 850; }
.af-label em.opt { background: #F1F3F7; color: #6B7080; }
.af-more { margin-left: auto; color: #9AA0B0; font-style: normal; font-weight: 700; }
.af-in { display: flex; align-items: center; margin: 1.754cqw 0 0; padding: 3.070cqw 3.947cqw; border-radius: 3.947cqw; background: #F1F3F7; color: #9AA0B0; font-size: 3.860cqw; font-weight: 600; }
.af-in i { margin-left: auto; font-style: normal; }
.af-seg { display: flex; gap: 2.632cqw; margin: 1.754cqw 0 0; }
.af-seg i { flex: 1; padding: 3.070cqw 0; border-radius: 3.947cqw; background: #F1F3F7; color: #9AA0B0; font-size: 3.860cqw; font-style: normal; font-weight: 800; text-align: center; }

/* 댓글 */
.app-cmts { display: flex; flex-direction: column; gap: 2.632cqw; margin: 0; padding: 0; list-style: none;
  min-height: 0; overflow: hidden; }
.app-cmts li span { display: block; color: #9AA0B0; font-size: 3.368cqw; font-weight: 700; }
.app-cmts li p { margin: 0.877cqw 0 0; color: #1A1D29; font-size: 3.719cqw; font-weight: 600; line-height: 1.45; }

.screen .app-rows { min-height: 0; overflow: hidden; }
.screen .app-rows li { padding: 2.193cqw 3.947cqw; }

/* ── 반쯤 걸친 것은 감춘다 ─────────────────────────────────────────────
   잘린 조각만 없애고 «글은 될수록 남긴다». 그래서 지우기 전에 먼저 납작하게
   만든다 — 소감을 한 줄로 줄이면 한 건이 83 → 69px 이 되어 둘이 더 오래 버틴다.
   목록에 돌아오는 키는 화면 키에서 176px 쯤(기기 줄 · 머리줄 · 검색칸 ·
   로그인 권유 · 사이)을 뺀 만큼이고, 검색칸을 접으면 33px 이 더 돌아온다.
     글 셋(83px) 261px → 화면 435px 부터
     글 둘(70px) 145px → 화면 321px 부터, 검색칸을 접으면 288px 부터
     글 하나       70px → 화면 212px 부터
   ★ @container 는 «안쪽 상자» 를 잰다. 화면에는 아래 여백 15px 이 있으므로
     문턱은 「화면 키 − 15 − 1」 로 적는다. 이걸 빼먹어 글 하나가 한 단 일찍
     사라졌다. */
@container (max-height: 434px) {
  .ap-body { -webkit-line-clamp: 1; }
}
/* 글 셋은 접지 않는다 — 옆 설명글이 「종목 이야기 세 건」 이라 적고 있고,
   글이 한 문장이 된 뒤로는 들어갈 자리가 남는다. 꺼 두고 잰어 보니 —
     화면 안쪽 456px  목록 자리 298 · 쓰는 높이 195 · 남는 높이 104
               312px           199 ·           126 ·            73
               231px           162 ·            88 ·            75
   폰은 clamp(240px, 33vh, 320px) 라 화면이 246px 아래로 안 내려간다.
   그 바닥에서도 75px 이 남으므로 감출 까닭이 없다.
   본문을 한 줄로 조이는 규칙(434)은 글이 길어질 때를 위한 안전줄로 남긴다. */
@container (max-height: 305px) { .app-seek { display: none; } }
/* 글 상세의 댓글도 같다 — 한 건이 30px 쯤이다. */
@container (max-height: 400px) { .app-cmts li:nth-child(2) { display: none; } }
@container (max-height: 330px) { .app-cmts li:nth-child(1) { display: none; } }

/* 맨 아래로 밀지 않는 꼬리글(.app-foot 은 margin:auto 로 바닥까지 내려간다) */
.app-foot.inline { margin: 0; text-align: left; line-height: 1.45; }

.app-draft { margin: 0; padding: 1.316cqw 3.509cqw; border-radius: 3.070cqw; background: #FFF3E2; color: #9F600A; font-size: 3.509cqw; font-weight: 850; letter-spacing: -.01em; text-align: center; }
.app-ask { margin: 0 0 0 8.772cqw; padding: 3.509cqw 4.386cqw; border-radius: 5.263cqw 5.263cqw 1.754cqw 5.263cqw; background: linear-gradient(100deg, #2B4BF2, #4F6BFF); color: #fff; font-size: 4.000cqw; font-weight: 700; line-height: 1.45; }
.app-answer { margin: 0; padding: 3.947cqw 4.386cqw; border-left: 3px solid #2B4BF2; border-radius: 1.754cqw 4.386cqw 4.386cqw 1.754cqw; background: #fff; color: #1A1D29; font-size: 3.930cqw; line-height: 1.5; }
.app-answer b { display: block; margin-bottom: 1.316cqw; color: #2B4BF2; font-size: 3.509cqw; font-weight: 850; letter-spacing: .04em; }
.app-note { margin: 0; padding: 3.509cqw 3.947cqw; border-radius: 3.947cqw; background: #fff; color: #4A4F63; font-size: 3.789cqw; line-height: 1.45; }
.app-note i { display: block; margin-bottom: 0.877cqw; color: #686F84; font-size: 3.439cqw; font-style: normal; font-weight: 850; }

/* === 포인트몰(.mall) — 갈래를 고르면 타일이 재배열된다 ==================
   근거는 마이디 앱 실측뿐이다 — 잔액 21,335P · 탭 다섯 · 총 31개 ·
   브랜드 여섯(스타벅스·해피콘·투썸플레이스·GS칼텍스·CU·GS25) · 갈래 넷 ·
   값이 확인된 상품 하나(네이버페이 포인트 5,000원 = 5,000P).
   상품도 가격도 이 밖으로는 한 줄도 늘리지 않았다.                       */

/* 이 화면이 지금 장면일 때만 폰이 손끝을 받는다. 다른 장면은 그대로 통과시킨다.
   전에는 「넷째 장면」으로 걸려 있었는데, 포인트몰이 몇 번째 장면인지는 줄기마다
   달라지므로 내용 이름(.mall)과 지금 장면(.is-now)의 교집합으로 바꿨다. */
.screen.mall.is-now { pointer-events: auto; -webkit-user-select: none; user-select: none; }

/* 손끝 파문(.ink)은 `.screen > *` 규칙에 걸려 흐름 요소가 되면 화면을 밀어낸다.
   포인트몰이 처음으로 포인터를 받는 화면이므로 여기서 자리를 되돌려 놓는다. */
.mall .ink { position: absolute; z-index: 0; }
/* 같은 함정이 파문을 쓰는 모든 판에 있다 — `.biz-card > *` · `.btn > *` 규칙이
   같은 특이도로 .ink 를 이겨 흐름 요소로 만든다. 한 자리씩 고치지 말고 못 박는다. */
.btn .ink, .biz-card .ink, .pick-card .ink, .tablist button .ink, .stage-steps li .ink { position: absolute; z-index: 0; }
@media (prefers-reduced-motion: reduce) {
  /* 멈춘 화면에서는 폰이 아니라 카드라, 어느 걸음이든 글을 끌어 고를 수 있어야
     한다. 전에는 포인트몰(.s4)에만 걸려 있었는데 세 줄기의 넷째 화면이 우연히
     함께 걸렸을 뿐이다. */
  .screen { pointer-events: auto; }
}

/* 아직 확인 중인 것을 확신형과 같은 자리에 앉히지 않는다 —
   되지 않은 일을 된 것처럼 적는 순간 나머지 문장까지 못 믿게 된다. */
.pillar-card li.yet { margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line); color: var(--muted); font-size: .86em; }
.pillar-card li.yet::marker { color: transparent; }

/* [hidden] 은 속성이라 특이도가 0 이다. 미디어쿼리 안 display:flex 가 이기므로
   넘길 것이 없을 때도 점이 떠 버린다. 못 박아 둔다. */
.rail-dots[hidden] { display: none !important; }

/* ── 그림 안에서 지나가는 것 ────────────────────────────────────────────
   여섯 카드의 그림은 그 제품이 하는 일을 **한 바퀴 돌며** 보여 준다.
   장식이 아니라 설명이다 — 승인이 떨어져야 데이터가 나가고, 처리는 기기 안에서
   끝나고, 권한 밖 문서는 빛을 받아도 어둡고, 오가는 것은 모델뿐이고,
   훑고 지나간 자리에서 판정이 서고, 평소 폭을 벗어난 점을 짚는다.

   카드가 화면에 들 때만 돈다(.is-seen). 나가면 선다.
   박자는 제품마다 다르다 — 여섯이 같은 박자로 뛰면 찍어낸 여섯 장으로 읽힌다. */
.biz-glyph g[class^="a-"] { animation-play-state: paused; }
.biz-card.is-seen .biz-glyph g[class^="a-"] { animation-play-state: running; }

/* ① 마이디 커넥트 — 요청 꾸러미가 건너가 승인 도장을 찍고, 그제야 데이터가 온다 */
.a-pkt   { animation: pkt 4.2s var(--settle) infinite; }
.a-stamp { animation: stamp 4.2s ease-in-out infinite; transform-origin: 177px 48px; }
.a-out   { animation: outp 4.2s var(--settle) infinite; opacity: 0; }
@keyframes pkt {
  0%, 4%   { transform: translate(88px, 48px); opacity: 0; }
  10%      { opacity: .95; }
  34%      { transform: translate(140px, 48px); opacity: .95; }
  40%, 100%{ transform: translate(140px, 48px); opacity: 0; }
}
@keyframes stamp {
  0%, 38%  { transform: scale(1); }
  44%      { transform: scale(1.13); }
  52%, 100%{ transform: scale(1); }
}
@keyframes outp {
  0%, 52%  { transform: translate(216px, 48px); opacity: 0; }
  58%      { opacity: .95; }
  86%      { transform: translate(268px, 48px); opacity: .95; }
  92%, 100%{ transform: translate(268px, 48px); opacity: 0; }
}

/* ② ODMPASS — 훑는 띠가 기기 안에서만 오르내리고, 바깥으로 나가는 길은 막혀 있다 */
@keyframes scan {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(28px); }
}
@keyframes barp {
  0%, 44%, 100% { opacity: .34; }
  56%           { opacity: .78; }
}

/* ③ SNPBrain — 질문의 빛이 왼쪽에서 지나가며 사내 문서만 밝힌다 */
.a-beam { animation: beam 5s cubic-bezier(.42,0,.58,1) infinite; opacity: .85; }
.a-doc  { animation: lit 5s ease-in-out infinite; animation-delay: var(--d, 0s); }
@keyframes beam {
  0%       { transform: translateX(0); opacity: 0; }
  8%       { opacity: .85; }
  68%      { transform: translateX(232px); opacity: .85; }
  78%, 100%{ transform: translateX(232px); opacity: 0; }
}
@keyframes lit {
  0%, 12%  { opacity: .42; }
  22%      { opacity: 1; }
  46%, 100%{ opacity: .42; }
}

/* ④ FL-STUDIO — 모델이 세 기관에서 가운데로 들었다가, 합쳐지면 고리가 되어 돌아간다 */
.a-orb  { animation: orb 3.6s var(--settle) infinite; animation-delay: var(--d, 0s); opacity: 0; }
.a-ring { animation: ringout 3.6s ease-out infinite; transform-origin: 150px 39px; opacity: 0; }
@keyframes orb {
  0%      { transform: translate(58px, 22px); opacity: 0; }
  10%     { opacity: .95; }
  46%     { transform: translate(150px, 39px); opacity: .95; }
  54%,100%{ transform: translate(150px, 39px); opacity: 0; }
}
@keyframes ringout {
  0%, 50% { transform: scale(1); opacity: 0; }
  58%     { opacity: .7; }
  100%    { transform: scale(2.5); opacity: 0; }
}

/* ⑤ SNPVision — 훑는 선이 지나가고, 지나간 자리에서 판정 틀이 조여든다 */
.a-sweep   { animation: sweep 4.6s cubic-bezier(.5,0,.5,1) infinite; }
.a-bracket { animation: snap 4.6s ease-out infinite; transform-origin: 150px 44px; }
@keyframes sweep {
  0%       { transform: translateX(50px); opacity: 0; }
  6%       { opacity: 1; }
  62%      { transform: translateX(250px); opacity: 1; }
  70%, 100%{ transform: translateX(250px); opacity: 0; }
}
@keyframes snap {
  0%, 30%  { transform: scale(1.16); opacity: .32; }
  44%      { transform: scale(.97); opacity: 1; }
  52%      { transform: scale(1); opacity: 1; }
  86%, 100%{ transform: scale(1); opacity: 1; }
}

/* ⑥ CataLogix — 값이 선을 따라 흐르다 벗어난 자리에서 고리가 퍼진다 */
.a-head  { animation: head 5.4s cubic-bezier(.45,0,.55,1) infinite; }
.a-spike { animation: spike 5.4s ease-out infinite; transform-origin: 118px 22px; opacity: .35; }
.a-pulse { animation: pulse 5.4s ease-out infinite; transform-origin: 118px 22px; opacity: 0; }
@keyframes head {
  0%      { transform: translate(16px, 50px); opacity: 0; }
  6%      { opacity: 1; }
  22%     { transform: translate(74px, 52px); }
  38%     { transform: translate(118px, 44px); }
  60%     { transform: translate(190px, 47px); }
  78%     { transform: translate(252px, 46px); opacity: 1; }
  88%,100%{ transform: translate(252px, 46px); opacity: 0; }
}
@keyframes spike {
  0%, 32% { opacity: .3; transform: scale(1); }
  40%     { opacity: 1; transform: scale(1.15); }
  56%,100%{ opacity: .6; transform: scale(1); }
}
@keyframes pulse {
  0%, 36% { transform: scale(1); opacity: 0; }
  42%     { opacity: .65; }
  70%,100%{ transform: scale(2.8); opacity: 0; }
}

/* 움직임을 끈 사람에게는 **끝난 상태**가 남는다 — 빈 그림이 아니다.
   승인이 찍히고 데이터가 건너간 뒤, 빛이 지나간 뒤, 판정이 선 뒤의 한 장. */
@media (prefers-reduced-motion: reduce) {
  .biz-glyph g[class^="a-"] { animation: none !important; }
  /* 낱낱까지 내려 준다 — animation 은 상속되지 않아 무리(g)만 끄면 그 «안»에
     걸린 것은 계속 돈다(Flow ERP 카드의 .a-feed circle · .a-rows path).
     1898행의 멈춤/돎 표는 이미 > * 까지 내려 주고 있다. */
  .biz-glyph g[class^="a-"] > * { animation: none !important; }
  .a-pkt   { transform: translate(140px, 48px); opacity: 0; }
  .a-out   { transform: translate(244px, 48px); opacity: .95; }
  .a-beam  { transform: translateX(232px); opacity: .5; }
  .a-doc   { opacity: 1; }
  .a-orb   { transform: translate(150px, 39px); opacity: .95; }
  .a-ring  { opacity: 0; }
  .a-sweep { transform: translateX(250px); opacity: .45; }
  .a-bracket { opacity: 1; }
  .a-head  { transform: translate(252px, 46px); opacity: 1; }
  .a-spike { opacity: .9; }
  .a-pulse { opacity: 0; }
}

/* ── FAQ 다섯 답의 그림 ──────────────────────────────────────────────
   패널 넷은 hidden 으로 태어난다. 효과 엔진은 파싱 때 크기가 0 이면 조용히
   포기하므로 여기에 캔버스를 두면 영영 살아나지 않는다 — 그래서 SVG 다.
   숨어 있어도 멀쩡하고, 보이는 순간부터 돈다.

   그림은 그 답을 그린다. 답을 읽기 전에 눈으로 먼저 안다.                */
.faq-art { display: block; width: 100%; max-width: 460px; height: auto; margin: 4px 0 0;
  color: #C8C2FF; opacity: .9; }
.tabpanel .faq-art g[class^="f-"], .tabpanel .faq-art .f-num, .tabpanel .faq-art .f-bar { animation-play-state: running; }
.tabpanel[hidden] .faq-art g[class^="f-"] { animation-play-state: paused; }
/* 휴대폰에서 그림 속 글자가 6~9px 로 줄어 읽히지 않았다 (2026-10-08). 글씨 크기가 그림의
   좌표 단위(8 · 8.5 · 9)로 박혀 있어 300 단위 그림이 200~290px 로 줄면 같이 준다.
   480px 아래에서만 13 단위로 키운다 — 그 위로는 그림이 커서 지금도 10px 을 넘는다.
   굵은 「100P」 · 「P」 는 font-weight 속성이 있어 빠진다. 그림 아래 설명 줄은 3 단위
   내려 커진 글씨가 도형에 닿지 않게 하고, 그만큼 그림 밑으로 나오는 것은 잘리지
   않게 둔다. 첫 답의 알약 여섯을 세 칸 두 줄로, 둘째 답의 「익명」 알약을 넓힌 것
   (문의.html)이 이 크기를 받치는 짝이다 — 영문 'Charging Station' · 'Anonymous' 가
   알약보다 길어 옆과 겹치던 것도 그쪽에서 풀린다. */
@media (max-width: 480px) {
  .faq-art { overflow: visible; }
  .faq-art text:not([font-weight]) { font-size: 13px; }
  .faq-art > text:not([font-weight]) { transform: translateY(3px); }
  .faq-art .f-anon text { font-size: 10px; }
}

.f-chip { animation: fchip 4.4s ease-out infinite; animation-delay: var(--d, 0s); opacity: .3; }
.f-bar  { animation: fbar 4.4s ease-out infinite; transform-origin: 8px 0; }
@keyframes fchip { 0%,4%{opacity:.28} 12%{opacity:1} 46%,100%{opacity:.62} }
@keyframes fbar  { 0%{transform:scaleX(0)} 52%,100%{transform:scaleX(1)} }

.f-anon { animation: fanon 4.6s var(--settle) infinite; opacity: 0; }
.f-hold { animation: fhold 4.6s ease-in-out infinite; }
.f-stay { animation: fstay 4.6s ease-in-out infinite; }
@keyframes fanon {
  0%,10%{transform:translate(150px,32px);opacity:0} 20%{opacity:.95}
  62%{transform:translate(268px,32px);opacity:.95} 70%,100%{transform:translate(268px,32px);opacity:0}
}
@keyframes fhold { 0%,100%{opacity:1} 50%{opacity:.72} }
@keyframes fstay { 0%,40%,100%{opacity:.5} 52%{opacity:1} }

.f-coin { animation: fcoin 4s var(--settle) infinite; animation-delay: var(--d, 0s); opacity: 0; }
.f-num  { animation: fnum 4s ease-out infinite; transform-origin: 222px 30px; }
@keyframes fcoin { 0%{transform:translateY(-16px);opacity:0} 14%{opacity:.9} 34%,100%{transform:translateY(0);opacity:.9} }
@keyframes fnum  { 0%,34%{transform:scale(.9);opacity:.5} 44%{transform:scale(1.06);opacity:1} 54%,100%{transform:scale(1);opacity:1} }

.f-swap { animation: fswap 4.2s var(--settle) infinite; opacity: 0; }
.f-cpn  { animation: fcpn 4.2s ease-out infinite; animation-delay: var(--d, 0s); opacity: .35; }
@keyframes fswap { 0%,6%{transform:translate(74px,30px);opacity:0} 16%{opacity:.9} 44%{transform:translate(124px,30px);opacity:.9} 52%,100%{transform:translate(124px,30px);opacity:0} }
@keyframes fcpn  { 0%,46%{opacity:.32} 58%{opacity:1} 84%,100%{opacity:.8} }

@keyframes fhit  { 0%{transform:translate(72px,17px);opacity:0} 12%{opacity:.95} 44%{transform:translate(150px,39px);opacity:.95} 52%,100%{transform:translate(150px,39px);opacity:0} }
@keyframes fans  { 0%,48%{opacity:.22} 62%{opacity:1} 88%,100%{opacity:.9} }
@keyframes fcite { 0%,62%{opacity:0} 74%{opacity:.62} 92%,100%{opacity:.62} }

/* 움직임을 끄면 끝난 상태 — 쌓였고, 바뀌었고, 답이 나온 뒤의 한 장 */
@media (prefers-reduced-motion: reduce) {
  .faq-art g[class^="f-"], .faq-art .f-num, .faq-art .f-bar { animation: none !important; }
  .f-chip { opacity: .8; } .f-bar { transform: scaleX(1); }
  .f-anon { transform: translate(268px, 32px); opacity: .95; } .f-hold { opacity: 1; } .f-stay { opacity: .8; }
  .f-coin { transform: translateY(0); opacity: .9; }
  .f-swap { transform: translate(124px, 30px); opacity: 0; } .f-cpn { opacity: .9; } .f-ans { opacity: .95; } .f-cite { opacity: .62; }
}

/* ── 폰 화면이 사진일 때 (.screen.shot) ──────────────────────────────
   마이디 여섯 걸음은 손으로 그린 근사치가 아니라 **실제 앱 화면**입니다.
   사진은 화면 칸을 가득 채웁니다 — 둘레에 여백을 두면 「화면 속 화면」이 되어
   진짜로 읽히지 않습니다. 폰 감싸개가 aria-hidden 이라 alt 는 낭독기에 닿지
   않지만, 사진이 안 뜰 때 무엇이었는지 남도록 적어 둡니다. */
.screen.shot { padding: 0; gap: 0; }

.screen.shot .app-shot {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
}

/* 움직임을 줄여 달라고 한 기기에서는 여섯 화면이 격자 칸으로 눕고 설명이
   사진 아래에 붙습니다. 그때는 사진이 제 비율대로 서야 합니다. */
@media (prefers-reduced-motion: reduce) {
  .story-stage .screen.shot { overflow: hidden; padding: 0; }
  .story-stage .screen.shot .app-shot { height: auto; border-radius: 15px 15px 0 0; }
  .story-stage .screen.shot .screen-say { margin: 0; padding: 12px 14px 14px; }
}

/* ── 무대 폰 크기 — 세 판이 함께 쓰는 단 한 줄 ────────────────────
   프로토타입 index.html · 라이브_홈탭 · 라이브_서비스탭의 폰은 테두리 두께도,
   모서리 곡률도, 그림자도, **크기 규칙도** 같아야 한다. 규칙을 판마다 두면
   반드시 어긋나므로(실제로 홈 탭에만 clamp(260,40vh,360) 이 따로 있었다)
   크기는 여기 한 줄로만 정하고, 두 라이브 판은 이것을 그대로 물려받는다.

   값의 까닭 — 무대는 100vh 를 셋으로 나눈 격자다(머리 · 무대 · 걸음 알약).
   가운데 칸은 대략 `100vh - 311px`, 폰 키는 폭의 2.04배에 18px 남짓이다.
   알약 위로 30px 넘게 띄우려면

       폭 ≤ (100vh - 361px) / 2.04  ≈  49vh - 173px

   이어야 한다. 앞서 쓰던 `47vh - 140px` 은 폰이 알약에 10~16px 까지
   다가붙어, 그림자(아래로 26px + 번짐 60px)가 알약을 덮었다.
   창이 낮으면 저절로 작아지고 높으면 320px 까지 큰다. 좁은 폭에서는 82vw 가
   먼저 걸려 판 밖으로 안 나간다. 셋 가운데 가장 작은 값이 이긴다. */
.story-stage .phone-body,
.svc-stage-phone .phone-body {
  /* 바닥값 130px — 창이 618px 보다 낮아지면 위 셈이 폰을 100px 아래로 줄여
     폰 꼴이 아니게 된다(470px 창에서 57px 이었다). 그 아래로는 무대 자체가
     들어갈 자리가 없으므로, 걸음 알약과 겹치더라도 폰은 폰으로 남긴다. */
  width: max(130px, min(320px, 82vw, calc(49vh - 173px)));
}

/* 바닥의 회사 정보 — 실제 홈페이지와 같은 글. 첫 칸에 넣으면 1.25fr(약 320px)
   안에서 주소가 석 줄씩 접히므로 격자 아래 한 줄짜리 칸으로 깐다. */
/* 브랜드 바로 아래에 붙는다 — 전에는 짜임 «밖» 에 있어 30px 이 필요했다 */
.footer-biz { margin-top: 18px; font-style: normal; }
.footer-biz p { margin: 0 0 7px; font-size: .78rem; line-height: 1.6; }
.footer-biz p:first-child { color: var(--text); font-weight: 700; }
.footer-biz p:last-child { margin-bottom: 0; }

/* 왼쪽 글이 빠지면 두 칸 격자가 한쪽만 차서 기운다. .solo 는 한 칸으로 세워
   가운데로 모은다 — 이 표시가 없는 두 칸 판은 그대로다. */
.contact-grid.solo { grid-template-columns: minmax(0, 720px); justify-content: center; gap: 26px; }
.contact-grid.solo .contact-copy { text-align: center; }
.contact-grid.solo .tablist { justify-content: center; }

/* ── 소개 갈래 — 머리띠에서 펼친다 ─────────────────────────────────────
   넓은 화면에서는 「소개」 를 누르거나 얹으면 아래로 펼쳐지고, 좁은 화면에서는
   햄버거 안에 한 칸 들여쓴 채 늘 펼쳐져 있다(누를 데가 두 번이면 번거롭다). */
.nav-drop { position: relative; display: inline-flex; align-items: center; }
.nav-menu { display: none; position: absolute; top: calc(100% + 15px); left: 50%; transform: translateX(-50%);
  gap: 2px; min-width: 150px; padding: 8px; z-index: 60; }
.nav-menu.is-open { display: grid; }
/* ── 세부탭은 «머리띠가 내려온 것» 처럼 ──────────────────────────────────
   떠 있는 카드가 아니다. 머리띠와 같은 바탕이 화면 폭 그대로 아래로 늘어나고,
   그 위에 이름이 놓인다 — 둥근 모서리도 그림자도 없고, 아래에 실선 하나만.

   판은 머리띠(.site-header)의 몫이다. 머리띠 폭이 아니라 «화면 폭» 이어야
   하고, 머리띠 아래끝에 틈 없이 붙어야 하기 때문이다. 그 덕에 손이 판 위에
   있는 동안에도 머리띠를 벗어난 것이 아니라, 따로 다리를 놓을 일이 없다.

   셈 —
     머리띠 92 · 탭 칸 44 → 탭 아래끝 68. 판은 92 에서 시작한다.
     목록은 판 윗변에서 --nav-list-top 만큼 내려 앉으므로, 탭 아래끝 기준
     24 + --nav-list-top 이다(24 = 92 − 68).
     --nav-list-h 는 가장 긴 목록(여섯 칸 × 44 + 틈 5 × 2 = 274)이다.
   760 아래는 서랍이라 이 셈이 없다. */
@media (min-width: 761px) {
  /* --nav-list-top 은 판 윗변(= 머리띠 아래끝)에서 목록까지의 띠다. 22 → 0.
     더 줄일 자리는 여기가 아니라 머리띠 자신이다 — 93 짜리 머리띠 안에서
     탭 칸 44 가 가운데 서 있어 위아래로 24씩 비어 있고, 목록은 그 아래에서
     시작할 수밖에 없다. 칸의 44(손가락이 닿을 최소 크기)도 건드리지 않는다. */
  .site-header { --nav-list-top: 0px; --nav-list-h: 274px; }

  .site-header:has(.nav-menu.is-open)::after {
    /* z-index 를 음수로 — 1150 이상에서 .nav-main 이 transform 으로 제 쌓기
       판을 만들어(z-index:auto = 0), 그 안의 목록이 아무리 60 이어도 머리띠의
       ::after(0)보다 위로 못 올라온다. 둘 다 0 이면 나중에 그린 ::after 가
       이겨 이름이 판 밑에 깔렸다. 판을 머리띠 «속 것들 뒤» 로 내린다. */
    content: ""; position: absolute; z-index: -1;
    top: 100%; left: 0; right: 0;
    height: calc(var(--nav-list-top) + var(--nav-list-h) + 30px);
    background: #0B1020; border-bottom: 1px solid var(--line);
  }

  /* 하나가 펴지면 넷이 모두 자리를 잡는다 — 보이는 것은 하나뿐이지만
     나머지 셋도 제 칸을 비워 둔다. */
  .nav-main:has(.nav-menu.is-open) .nav-menu { display: grid; visibility: hidden; }
  /* 무게를 맞춰 적는다 — 위가 (0,3,0) 이라 `.nav-menu.is-open`(0,2,0) 으로는
     펴 놓고도 넷이 다 숨었다. 이 파일에서 되풀이되는 탈이다. */
  .nav-main:has(.nav-menu.is-open) .nav-menu.is-open { visibility: visible; }

  .nav-menu {
    top: calc(100% + 24px + var(--nav-list-top)); left: 0; transform: none;
    min-height: var(--nav-list-h);
    align-content: start;
    padding: 0; border: 0; border-radius: 0;
    background: none; box-shadow: none; z-index: 60;
  }
}
.nav-menu a { padding: 7px 0; border-radius: 0; white-space: nowrap; background: none; }
.nav-menu a:hover, .nav-menu a:focus-visible { background: none; color: var(--text) !important; }
.nav-menu a[aria-current="page"] { color: var(--text) !important; font-weight: 900; background: none; box-shadow: none; }

@media (max-width: 760px) {
  .nav-drop { display: block; }
  .nav-menu { display: block; position: static; transform: none; min-width: 0;
    padding: 0 0 0 15px; border: 0; border-radius: 0; background: none; box-shadow: none; }
  .nav-menu a { padding: 10px 4px; border-radius: 0; font-size: .86rem; }
}

/* ── 판을 액자에 넣는다 ───────────────────────────────────────────────────
   크라켄 결: 바탕 위에 모서리 둥근 판이 떠 있고, 그 사이로 바탕이 비쳐
   테두리처럼 보인다. 그쪽은 바탕이 희고 판이 어둡다. 우리는 반대로 어두운
   판이므로, 흰 실선은 아주 옅게 깔고(6%) 판을 바탕보다 한 단 띄운다.

   판이 되면 «모서리를 도는 선» 이 생긴다 — 이 선 하나가 «판이 끝났다» 를
   말해 주므로, 켜를 가르려고 두던 아래 테두리(.big + .big)는 걷어도 된다.

   전체 너비 조각(스티키 무대 · 가로 레일)은 판 밖에 있어 잘리지 않는다.
   .section 에는 overflow 를 걸지 않는다 — 걸면 sticky 가 죽는다.        */
main > section {
  margin: 13px;
  border: 1px solid rgba(255, 255, 255, .11);
  border-radius: 30px;
  /* 위 모서리에 얇은 빛 — 판이 바탕에서 «떠 있다» 고 말해 주는 한 줄 */
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06);
}
main > section:not(.page-hero):not(.section-white) { background: #121A2E; }

/* ── 제목 판은 글 쪽으로 반쯤 당긴다 ─────────────────────────────────────
   판은 화면 끝에서 13px 떨어져 서고, 그 판 안에서 글 통이 다시 66px 안으로
   들어온다. 그래서 판 가장자리와 글 사이가 1440 에서 109px · 1280 에서 33px 씩
   비어 있었다. 그 «속 여백» 을 절반으로 줄인다 — 글 폭은 한 자도 건드리지 않고
   판만 안으로 들어온다.

   폭을 둘 중 작은 것으로 고른다 —
     100% - 59px  글 통이 1180 에 닿기 «전» 구간. 속 여백 33 → 16.5 가 된다.
     577px + 50%  글 통이 1180 에 걸린 «뒤» 구간. (판 + 글)의 한가운데 값이다.
   1425 에서 1399 → 1289, 1265 에서 1239 → 1206, 1085 에서 1059 → 1026.

   글 통의 안쪽 들임도 66 → 33 으로 함께 줄여야 한다. 안 그러면 좁아진 판에서
   통이 다시 66 을 물려 «글까지» 같이 좁아진다 — 줄이려던 것은 여백뿐이다.

   판 «전부» 에 건다 — 제목 판만 좁히면 그 아래 판들이 13px 자리에 남아 세로선이
   두 칸으로 어긋난다. 주소가 든 바닥글도 같은 판이므로 함께 묶는다.

   되돌린 자리 — 한때 「속 여백을 통째로 절반」(100% - 59px · 577px + 50%)까지
   당겼더니 판이 답답했다. 지금은 그 절반, 즉 «옛 폭과 그 값의 한가운데» 에 세운다.
   양옆에 드러나는 흰 바탕이 1265 에서 13 → 21 · 1425 에서 13 → 40 · 1585 에서
   13 → 60 이 된다(통째로 절반이던 때는 30 · 68 · 108 이었다).

   통의 들임이 49px 인 까닭 — 판이 좁아진 만큼 통도 덜 물려야 «글 폭이 옛날 그대로»
   남는다. 1265 에서 1171 · 1085 에서 991 로, 좁히기 전과 한 자도 다르지 않다.

   한 칸으로 접히는 1000 아래에서는 걸지 않는다 — 거기서는 판이 이미 화면만 하고,
   더 좁히면 글 줄이 먼저 무너진다. */
@media (min-width: 1001px) {
  main > section,
  footer.footer { width: min(calc(100% - 43px), calc(276px + 75%)); margin-inline: auto; }
}
/* 이어 붙는 CTA 띠는 앞 판에 딸린 꼬리다 — 둘이 «한 판» 이 되도록 맞물린 쪽의
   모서리와 테를 양쪽 다 죽인다. 한쪽만 죽이면 위 판의 둥근 아래 모서리가 아래
   판의 각진 위 모서리에 얹혀 흰 홈이 파인다.

   모서리는 «네 귀를 한꺼번에 적는 약식» 이 아니라 귀마다 따로 적는다. 한 판이
   위로도 아래로도 맞물릴 수 있는데, 약식으로 적으면 뒤에 오는 규칙이 앞 규칙이
   편 귀를 도로 둥글게 만든다 — 실제로 그랬다. 인덱스의 사이 문장을 걷자
   `flow-cta + section` 다음에 오는 판이 «또 flow-cta 를 거느린» 줄기가 되면서,
   그 줄기의 아래 두 귀가 30px 로 되살아나 홈이 파였다. 귀마다 적으면 두 규칙이
   싸우지 않고 포개진다. */
main > section.flow-cta {
  margin-top: -13px; border-top: 0;
  border-top-left-radius: 0; border-top-right-radius: 0;
}
main > section:has(+ section.flow-cta) {
  border-bottom: 0;
  border-bottom-left-radius: 0; border-bottom-right-radius: 0;
}
.section-white { background: var(--surface); }
.page-hero { overflow: hidden; }          /* 히어로의 흐르는 빛만 모서리에 맞춘다 */

/* 판이 안쪽으로 26px 들어왔으니 통도 그만큼 좁힌다 */
main > section > .container { width: min(1180px, calc(100% - 66px)); }
/* 판을 글 쪽으로 반쯤 당긴 폭(위 @media min-width:1001px)에서는 통의 들임도
   절반이어야 «글 폭이 그대로» 남는다. 이 줄이 저 위가 아니라 여기 있는 까닭 —
   바로 윗줄과 특이도가 같아, 위에 두면 윗줄이 뒤에 와서 이긴다(실제로 졌다:
   1280 에서 글이 1171 이어야 하는데 1138 로 줄었다). */
@media (min-width: 1001px) {
  main > section > .container { width: min(1180px, calc(100% - 49px)); }
}

/* 켜를 가르던 선들은 이제 액자가 대신한다 */
.big + .big { border-top: 0; }

@media (max-width: 760px) {
  main > section { margin: 9px; border-radius: 22px; }
  main > section.flow-cta { margin-top: -9px; }
  main > section > .container { width: calc(100% - 40px); }
}

/* ── 바탕을 흰 쪽으로 뒤집는다 ─────────────────────────────────────────
   첨부 영상의 결: 바탕이 희고 그 위에 어두운 판이 떠 있다. 판 안쪽은 그대로
   어두우므로, 글자색은 «판 안» 과 «판 밖» 을 갈라 준다. 파일 맨 위의 강제
   테마가 !important 로 못 박아 두었으므로 여기서도 같은 무게로 되짚는다. */
html, body { background: #F4F3F7 !important; color: #14182A !important; }

/* 판 안은 예전 그대로 — 어두운 바탕에 밝은 글씨 */
main > section, .footer { color: var(--text); }

/* 머리띠 — 흰 판 */
/* 판이 머리띠 밑으로 지나가므로 반투명이면 글씨가 비친다 — 꽉 채운다 */
.site-header { background: #fff !important; border-bottom: 1px solid rgba(20, 24, 42, .10) !important; }
.site-header .brand-name, .hamburger { color: #14182A; }
.site-nav a { color: #5A6478 !important; }
.site-nav a:hover, .site-nav a:focus-visible { color: #14182A !important; }
.site-nav a.cur, .site-nav a[aria-current="page"] { color: #14182A !important; }
.language { color: #8A93A6; }
.lang-btn { color: #5A6478; }
.lang-btn.is-on { background: rgba(107, 92, 230, .16); color: #2E2496; }
/* 목록에는 제 바탕을 주지 않는다 — 판이 이미 깔려 있어, 여기에 흰 바탕을
   더 깔면 큰 판 위에 흰 기둥이 하나 더 서서 화면이 둘로 읽힌다.
   이 줄이 1493행의 background:none 보다 «뒤에» 있어 이겨 왔다. */
.site-header:has(.nav-menu.is-open)::after { background: #fff; border-bottom-color: rgba(20, 24, 42, .10); }
.nav-menu a:hover, .nav-menu a:focus-visible { background: none; color: var(--purple) !important; }
.nav-menu a[aria-current="page"] { color: #14182A !important; background: none; font-weight: 900; }
.skip-link { background: #14182A; color: #fff; }

/* 바닥도 판 하나로 — 바탕 위에 떠 있게 */
.footer {
  margin: 13px; border: 1px solid rgba(255, 255, 255, .11); border-radius: 30px;
  background: #121A2E !important;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06);
}

@media (max-width: 760px) {
  .site-nav { background: #fff; border-bottom: 1px solid rgba(20, 24, 42, .10); }
  .site-nav a { border-bottom: 1px solid rgba(20, 24, 42, .08); }
  .footer { margin: 9px; border-radius: 22px; }
}

/* ── 제목이 «흐린 그림자에서 또렷해진다» ─────────────────────────────────
   처음엔 마스크 아래에서 통째로 올라오게 했는데, 흰 제목이 두 겹으로 겹쳐
   보였다. 이제 감추지 않는다 — 제목은 처음부터 «그림자처럼» 흐리게 놓여
   있다가, 줄마다 0.09초씩 늦게 떠오르며 또렷해진다. 자리는 처음부터 제자리라
   겹칠 것이 없다.

   자바스크립트가 줄을 쪼개고 <html> 에 .js-wipe 를 단 뒤에만 걸린다. 그 표가
   없으면 아무것도 흐려지지 않는다 — 스크립트가 막힌 자리에서 제목이 흐린 채
   남으면 안 된다. */
.js-wipe .wipe { display: block; }
.js-wipe .wipe > span { display: block; opacity: .16; filter: blur(7px);
  transform: translateY(.17em) scale(.994); transform-origin: 0 50%;
  transition: opacity .82s var(--settle), filter .82s var(--settle),
              transform .9s cubic-bezier(.16, .84, .28, 1); }
.js-wipe .is-wiped .wipe > span { opacity: 1; filter: blur(0); transform: none; }
.js-wipe .is-wiped .wipe:nth-child(2) > span { transition-delay: .09s; }
.js-wipe .is-wiped .wipe:nth-child(3) > span { transition-delay: .18s; }
.js-wipe .is-wiped .wipe:nth-child(4) > span { transition-delay: .27s; }
/* 두 몸짓이 겹치면 지저분하다 — 쪼갠 제목은 제 페이드를 끄고 이쪽에 맡긴다 */
.js-wipe .reveal.has-wipe { opacity: 1 !important; transform: none !important; }

/* 무대 제목 셋을 한 모양으로 ── 첫 줄기의 제목은 <h1>, 나머지 둘은 <h2> 다.
   맨 위 `h1{…color:var(--text)!important}` 가 <h1> 의 투명 글자만 눌러, 같은
   무대인데 첫 줄기만 민색이고 둘·셋은 그라데이션이었다. 첫 줄기를 되살려 맞춘다.
   이 선택자는 692줄에서 «배경과 투명 글자를 짝으로» 주므로, 여기서 투명만
   되돌려도 글자가 사라질 일이 없다.
   (같은 까닭으로 히어로 <h1> 스물셋의 그라데이션도 죽어 있다. 그쪽은 흰 바닥에
    앉는 판이 섞여 있어 따로 봐야 하므로 여기서는 손대지 않는다.) */
.stage-head h1 { color: transparent !important; }

/* 좁은 화면에서 세부 갈래는 «내비 안의 한 줄» 이지 떠 있는 카드가 아니다.
   760px 아래 규칙이 카드 꼴을 걷어 놨는데, 뒤에 온 흰 바닥 블록이 배경과
   그림자를 다시 얹어 메뉴 안에 카드가 떠 보였다. */
@media (max-width: 760px) {
  .nav-menu { background: none; box-shadow: none; border-color: transparent; }
}

/* ── 히어로 제목의 그라데이션을 되살린다 ────────────────────────────────────
   맨 위 `h1{…color:var(--text)!important}` 가 108줄·692줄이 «배경과 짝으로»
   준 투명 글자를 눌러, 스물둘의 그라데이션이 죽어 있었다. 이 두 선택자는
   언제나 배경을 함께 주므로 투명만 되돌려도 글자가 사라질 일이 없다.
   바탕도 확인했다 — 히어로 배경은 두 종류뿐이고 둘 다 짙은 남색이다
   (가장 밝은 색 구간의 밝기 0.25 미만). */
.hero h1, .page-hero h1 { color: transparent !important; }

/* ── 머리띠의 마크를 맨 왼쪽까지, 두 배로 ───────────────────────────────────
   통(.container)이 양옆에 물려 두던 여백을 왼쪽만 걷어 마크가 화면 맨 끝에서
   시작한다. 마크는 27×26 → 54×52. 머리띠 키도 그만큼 키워 마크가 눌리지
   않게 한다. 오른쪽 메뉴는 통의 여백을 그대로 쓴다. */
.site-header .nav-wrap { padding-left: 0; height: 92px; }
/* padding-left 는 아래 22px 줄이 정한다 — 여기 적어도 덮인다. */
.site-header .brand { gap: 13px; font-size: 1.32rem; }
.site-header .brand-cube { width: 36px; height: 35px; perspective: 253px; }   /* 54×52 를 1.5 로 나눈다 — 글자는 그대로 */
.site-header .bc-shell { transform: translateZ(4.7px); }
.site-header .bc-core { transform: translateZ(-4.7px); }

/* ── 머리띠 다시 짜기 ───────────────────────────────────────────────────────
   마크는 화면 맨 왼쪽에서 시작하고, 메뉴 넷은 가로 가운데에 선다. 받기 단추는
   오른쪽 끝에 붙는다. 넷을 가운데로 미는 것은 양쪽의 auto 여백 둘이다 —
   왼쪽은 첫 항목이, 오른쪽은 첫 단추가 민다. */
.site-header .nav-wrap { position: relative; width: 100%; max-width: none; margin: 0; padding: 0 30px 0 0; }
.site-header .brand { padding-left: 22px; }

/* 좁은 화면의 마크 들임 — 이 덩이는 위 22px 줄 «뒤» 에 있어야 한다.
   선택자가 같아 무게가 같으므로(0,2,0) 순서가 정한다. 앞에 두었더니 360 과
   760 에서 14 가 아니라 22 로 앉았다(2026-09-28 에 재어 확인). */
@media (max-width: 760px) {
  .site-header .nav-wrap { height: 76px; }
  .site-header .brand { padding-left: 14px; font-size: 1.16rem; }
  .site-header .brand-cube { width: 28px; height: 27px; }
}
/* 아래 규칙은 «넓은 화면» 것이다. 760px 아래에서는 내비가 서랍으로 접히는데,
   폭을 안 가리고 flex-row 를 씌웠더니 서랍이 가로로 펴져 97px 이 삐져나갔다. */
@media (min-width: 761px) {
  .site-header .site-nav { flex: 1; display: flex; align-items: center; justify-content: flex-end; gap: 8px; font-size: 1.06rem; }
  /* 탭 사이 틈 — 목도리가 양옆으로 8px 씩 나오므로 16px 은 먹고 들어간다.
     30 → 44 로 벌려 목도리끼리 12px 이 남는다. */
  .site-header .nav-main { display: flex; align-items: center; gap: 36px; }
}
/* 넉넉한 폭에서는 넷을 «화면» 가운데에 세운다. 세로도 함께 가운데로 —
   top 을 안 주면 제자리(정적 위치)에 머물러 위아래가 어긋난다.
   좁아지면 흐름으로 돌려 놓는다: 절대 위치인 채로 좁아지면 받기 단추와 겹친다.

   분기점이 1080 인 까닭 — 이 겹침은 «영문» 에서 난다. 가운데 넷이 국문 192 ·
   영문 293 이고, 오른쪽에는 Google Play · App Store · KR/EN 이 늘 선다. 1000 에
   두었더니 영문에서 950~1040 이 절대 위치로 들어와 받기 단추를 21px 파고들었다
   (1000 에서 21 · 1020 에서 11 · 1041 에서 0). 폭 1px 마다 0.5px 씩 벌어지므로
   단추 사이 틈(20px)만큼 띄우려면 그만큼이 필요하다. 국문은 애초에 안 겹치지만
   분기점은 하나뿐이라, 겹치는 쪽에 맞춘다 — 가운데 정렬은 취향이고 겹침은 탈이다.

   2026-09-22 에 1080 → 1150 으로 올렸다. 탭 이름이 소개 → 기업소개 · 문의 →
   문의 · 안내 처럼 길어지며 가운데 넷이 영문 293 → 356 이 되어 1080 에서 다시
   12px 파고들었다. 같은 까닭으로 아래 「글자 줄이는 띠」도 1160 → 1220 으로 늘렸다 —
   1160 에서 글자가 커지며 356 → 411 이 되어 거기서 또 한 번 부딪혔다(1161 에서 3px). */
@media (min-width: 1150px) {
  .site-header .nav-main { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); }
}
@media (min-width: 761px) and (max-width: 1149px) {
  .site-header .nav-main { margin-right: auto; margin-left: 24px; }
}
.site-header .site-nav a:not(.nav-beta) { font-size: 1.06rem; font-weight: 750; }

@media (min-width: 761px) and (max-width: 1220px) {
  .site-header .site-nav { gap: 20px; font-size: .98rem; }
  .site-header .nav-main { gap: 26px; }   /* 목도리 16 을 빼고 10 이 남는다 */
  .site-header .site-nav a:not(.nav-beta) { font-size: .98rem; }
}

/* 761~949 — 영문에서만 머리띠가 탈이 났다. 790 폭에서 재면 국문 메뉴통 192 로
   쪽폭 775(안 넘침), 영문은 292 라 언어 고르개가 823 까지 밀려 48px 넘친다.
   영문 탭 이름(About · Services · Solutions · Contact)이 국문보다 100px 넓다.
   가장 좁은 761 에서는 통이 746 이라 77px 을 줄여야 한다.
   좁혀야 하는 폭은 860 에서 끝나지 않는다 — 861~940 은 넘치진 않지만 단추가
   눌려 「Google Play」가 세 줄로 접힌다(키 44 → 53). 950 부터 한 줄로 돌아온다.
   그 세 줄 접힘은 전부터 있던 것이고, 이번에 폭을 촘촘히 재다 드러났다.
   서랍으로 되돌리지 않은 까닭 — 국문에서는 이 폭에서 멀쩡히 들어가는데 탭 넷을
   햄버거 뒤로 숨기는 것이 된다. 틈과 글자를 한 단씩 줄인다.
   구조(display · position)는 한 줄도 건드리지 않는다. */
@media (min-width: 761px) and (max-width: 949px) {
  .site-header .site-nav { gap: 8px; }
  .site-header .nav-main { gap: 20px; }   /* 목도리 16 을 빼고 4 가 남는다 */
  .site-header .site-nav a:not(.nav-beta) { font-size: .84rem; }
  /* 단추는 안 줄어들게 못 박는다 — flex 는 자리가 모자라면 여기부터 줄이는데,
     761 영문에서 96 → 63 까지 눌려 「Google Play」가 두 줄로 접혔다.
     모자라는 자리는 탭 글자에서 뺀다. */
  /* 화살표는 접는다 — 새 창으로 뜬다는 것은 aria-label 과 rel 이 이미 말한다 */
  /* 761~789 영문에서 KR/EN 이 14px 삐져나갔다. 머리띠에 선 것은 마크 · 탭 넷 ·
     받기 둘 · KR/EN 이고 그 합이 760 인데 쓸 수 있는 폭이 746 이다. 탭 글자는
     이미 .84rem 까지 줄였으므로, 남은 자리는 «사이» 와 «마크» 에서 뺀다 —
     마크는 1.32rem·36px 로 두 배 키워 둔 것이라 여기서 한 단 내려도 여전히 크다. */
  .site-header .nav-wrap { gap: 12px; padding-right: 16px; }
  .site-header .brand { padding-left: 14px; gap: 9px; font-size: 1.12rem; }
  .site-header .brand-cube { width: 30px; height: 29px; }
}

/* 아주 좁은 화면 — 머리띠에 남는 것은 마크 · 햄버거 · KR/EN 셋뿐인데, 그 사이를
   26px 로 벌려 두면 320 에서 셋의 합이 316px 이라 쓸 수 있는 305 를 11px 넘었다
   (21쪽 전부에서 같은 값으로 났다). 글자 크기는 그대로 두고 사이만 줄인다 —
   줄이는 것이 글자면 마크 이름이 먼저 흐려지고, 그 이름이 이 띠의 전부다. */
@media (max-width: 359px) {
  .site-header .nav-wrap { gap: 12px; }
}

/* 바닥에 붙는 받기 띠도 둘로 — 이름 한 번, 가게 둘 */
@media (max-width: 760px) {
  .mobile-beta { position: fixed; display: flex; align-items: center; gap: 8px;
    left: 14px; right: 14px; bottom: 14px; z-index: 45; min-height: 50px; padding: 0 10px 0 14px;
    border-radius: 11px; background: var(--purple); color: #fff; font-weight: 850;
    box-shadow: 0 12px 30px rgba(3,8,22,.35); }
  .mobile-beta b { margin-right: auto; font-size: .92rem; }
  /* 칩을 «밝게» 깔면 흰 글씨가 3.66 까지 떨어진다 — 어둡게 깔아야 6.8 이다 */
  /* 칩 높이는 a 의 min-height 44px 인데 글줄(21px)이 위쪽 padding 에 붙어 앉아
     글자가 가운데보다 4.5px 위에 떴다(위 10 · 아래 19). 칩 안에서 세로 가운데로 세운다 —
     칩의 크기 · 색 · 모서리는 그대로다. (2026-10-08) */
  .mobile-beta a { display: flex; align-items: center; padding: 7px 11px; border-radius: 8px; background: rgba(9,12,28,.22);
    color: #fff !important; font-size: .82rem; font-weight: 850; white-space: nowrap; }
}

/* 서랍 안에서는 메뉴 통도 세로로 편다 — 가로 flex 인 채로 두면 넉 줄이 한 줄에 눌린다.
   .site-nav 에 display 를 적었던 줄은 걷었다: (0,2,0) 이라 닫힌 상태의
   .site-nav{display:none} (0,1,0) 을 이겨, 서랍이 «영영 열린 채» 였다.
   되돌리려던 flex-row 는 이미 @media (min-width: 761px) 안이라 여기까지 오지 않는다. */
@media (max-width: 760px) {
  .site-header .nav-main { display: flex; flex-direction: column; align-items: stretch; gap: 0; }
  /* 서랍 안에서는 밑줄을 걷는다 — 줄이 칸 너비(358px)로 늘어나 «표시» 가 아니라
     «칸 나누는 선» 으로 읽힌다. 세로로 선 서랍에서는 색과 굵기만으로 충분하다. */
  .site-header .nav-main > a.cur:not(.nav-beta),
  .site-header .nav-main > a[aria-current="page"]:not(.nav-beta),
  .site-header .nav-drop > a.cur,
  .site-header .nav-drop > a[aria-current="page"] { background-image: none; }
}

/* ⑥ SNPFlow ERP — 따로 놀던 장부 셋(사람 · 매출 · 재고)이 한 판으로 흘러들고,
   그 판의 줄이 그 차례대로 찬다. 셋이 «동시에» 가면 합치는 일로 안 보인다. */
.a-feed circle { animation: erp-feed 4.2s var(--settle) infinite; opacity: 0; }
.a-feed circle:nth-child(2) { animation-delay: .5s; }
.a-feed circle:nth-child(3) { animation-delay: 1s; }
@keyframes erp-feed {
  0%       { transform: translateX(0); opacity: 0; }
  12%      { opacity: .95; }
  50%      { transform: translateX(98px); opacity: .95; }
  58%, 100%{ transform: translateX(98px); opacity: 0; }
}
.a-rows path { animation: erp-row 4.2s ease-in-out infinite; opacity: .26; }
.a-rows path:nth-child(2) { animation-delay: .5s; }
.a-rows path:nth-child(3) { animation-delay: 1s; }
@keyframes erp-row { 0%, 46% { opacity: .26; } 56% { opacity: 1; } 84%, 100% { opacity: .26; } }

/* ⑦ SNPScan — 빛줄이 바코드를 훑고, 그 값이 건너가 재고 수를 제자리로 돌린다.
   훑기가 끝난 «뒤에» 값이 건너가고, 건너간 뒤에 표가 선다 — 차례가 곧 이야기다. */
.a-beam2 { animation: scan-beam 3.2s ease-in-out infinite; }
@keyframes scan-beam {
  0%, 100% { transform: translateY(0); opacity: .3; }
  46%      { transform: translateY(24px); opacity: .85; }
}
.a-dot2 { animation: scan-dot 3.2s var(--settle) infinite; opacity: 0; }
@keyframes scan-dot {
  0%, 48%  { transform: translateX(0); opacity: 0; }
  54%      { opacity: .95; }
  80%      { transform: translateX(58px); opacity: .95; }
  86%, 100%{ transform: translateX(58px); opacity: 0; }
}
.a-tick2 { animation: scan-tick 3.2s ease-out infinite; opacity: 0; transform-origin: 235px 52px; }
@keyframes scan-tick {
  0%, 80%  { opacity: 0; transform: scale(.66); }
  88%      { opacity: 1; transform: scale(1.14); }
  94%, 100%{ opacity: 1; transform: scale(1); }
}

/* 위 둘은 무리(g) 가 아니라 «그 안의 낱낱» 이 저마다 늦게 움직인다 —
   멈춤/돎 표도 낱낱까지 내려 줘야 카드가 화면 밖일 때 멎는다. */
.biz-glyph g[class^="a-"] > * { animation-play-state: paused; }
.biz-card.is-seen .biz-glyph g[class^="a-"] > * { animation-play-state: running; }

/* ── 제목 화면은 잠시 멈춘다 (2026-09-22) ────────────────────────
   .hero-art 는 그림만 들어 있는 빈 칸이라, 그림을 멈추면 네 쪽에서
   빈 박스만 남는다. 함께 접는다 — 히어로 키는 .page-hero > .container 의
   min-height:380px 가 잡고 있어 줄지 않는다.
   되살릴 때는 이 덩이와 app.js 의 __paiHeroStill 을 같이 걷는다. */
.page-hero .hero-art { display: none; }

/* ── 휴대폰에서 무대가 제 칸을 넘치던 것 (2026-10-06) ────────────────
   실제 배포 뒤 375px 화면에서 글자가 서로 겹쳤다. 재어 보니 까닭은 둘이다.

   ① 폰이 제 «폭» 으로만 커서 장면 칸을 넘쳤다
      무대는 100vh 에 갇힌 격자(머리 · 장면 · 걸음표)인데, .phone-body 의
      크기를 폭(clamp)으로만 정해 두었다. 375x812 에서 장면 칸은 570px 인데
      폰이 459px + 설명 129px = 606px 을 요구해, 설명이 칸을 넘쳐 아래
      걸음표 위에 얹혔다(「열리는」 ✕ 「01」 처럼 열 쌍이 겹쳤다).
        폰 높이를 남은 칸에 맞춘다 — 폭은 aspect-ratio 가 따라온다.
        어떤 화면 높이에서도 스스로 들어맞는다.

   ② 아래 띠(마이디 받기)가 무대 바닥을 덮었다
      띠는 fixed 라 자리를 차지하지 않는다. 무대 바닥 78px 을 비워 둔다.

   그리고 무대를 머리띠 «아래» 에 붙인다(top: --hd). 전에는 top:0 이라,
   붙기 전(맨 위)에는 머리띠 높이만큼 내려앉아 바닥이 띠에 가리고, 붙은
   뒤에는 제자리로 올라오며 레이아웃이 한 번 튀었다. 처음부터 같은 자리다.
   --hd 는 app.js 가 재어 넣는다(없으면 86px).

   확인: 375x812 에서 스크롤 0 · 120 · 300 · 1200 네 자리 모두 겹침 0.

   「동작 줄이기」 에서는 걸지 않는다 (2026-10-07). 그때는 무대가 붙박이가
   아니라 카드를 세로로 편 스토리보드다(771행). 이 덩이가 더 뒤에 있어
   그쪽의 height:auto 를 이기는 바람에, 375px 에서 735px 칸에 카드 여섯 장
   (1,712px)이 갇혀 977px 이 아래 내용 위로 넘쳤다.                        */
@media (max-width: 760px) and (prefers-reduced-motion: no-preference) {
  .story-stage { top: var(--hd, 86px); height: calc(100vh - var(--hd, 86px)); padding-bottom: 78px; }
  .stage-scene { grid-template-rows: minmax(0, 1fr) auto; align-items: stretch; min-height: 0; }
  .stage-phone { min-height: 0; display: grid; place-items: center; }
  .story-stage .phone-body { height: 100%; width: auto; max-width: 100%; }

  /* ── 아이폰에서 폰이 가느다란 막대로 찌그러졌다 (2026-10-08) ──────────
     세연 님이 실제 아이폰(네이버 앱 안 브라우저, 390 x 686)에서 본 것 — 폰이
     폭 20px 짜리 기둥으로 서 있었다. 위 줄은 키를 100% 로 잡고 폭은 aspect-ratio
     가 «키에서» 끌어오게 맡겼는데, 사파리 계열(WebKit)은 폭을 키보다 먼저 정한다.
     그때 100% 는 아직 모르는 값이라 폭이 속 내용만큼(안여백 18 + 테두리 2)으로
     주저앉는다. 크롬은 한 번 더 돌아 맞추므로 미리보기에서는 멀쩡했다.
       퍼센트에 기대지 않는다. index.html 의 구동부가 칸의 키를 «재어» 픽셀로
       넘기고(--slot-h · --slot-w), 폰은 그 값을 그대로 쓴다. 값이 아직 없으면
       (스크립트 전 한 프레임 · 옛 index.html) 뒤의 값이 위 줄과 같은 뜻이다.

     같이 잡은 것 둘 — 재어 보니 실제 휴대폰의 화면 키는 주소창 · 도구 막대를
     빼면 640~700px 이라, 크롬에서도 폰이 61~84px 폭으로 쪼그라들어 있었다.
       ① 위 여백 72px 은 무대가 쪽 맨 위(top:0)에 붙던 때 머리띠를 비키려던
          것이다. 10-06 에 무대를 머리띠 «아래» 에 붙인 뒤로는 빈 자리일 뿐이라
          22px 로 줄여 폰에게 돌려준다(390 x 686 에서 폰 키 125~171 → 175~221).
       ② 키는 100svh 로 잡는다 — 사파리의 도구 막대가 «나와 있을 때» 의 키다.
          100vh 는 막대가 들어간 때의 키라, 막대가 나오면 걸음표가 그 밑에 깔린다.
          모르는 브라우저는 윗줄의 100vh 를 쓴다.
       ③ 바닥값 560px 을 푼다. 화면이 그보다 낮으면 무대가 화면보다 길어져
          걸음표가 화면 밖으로 나갔다. */
  .story-stage {
    height: calc(100svh - var(--hd, 86px)); min-height: 0; padding-top: 22px;
  }
  .story-stage .phone-body { height: var(--slot-h, 100%); width: var(--slot-w, auto); }

  /* 폰은 늘 같은 크기로 서고, 무대가 낮으면 글 쪽이 접힌다 — 단은 index.html 이
     무대의 키를 보고 붙인다(까닭과 숫자는 그쪽 주석에).
       .is-short  설명 위의 큰 번호(40px)를 접고 제목을 한 치 줄인다
       .is-tight  설명의 둘째 글(작은 글)도 접는다 */
  .story-stage.is-short .say-num { display: none; }
  .story-stage.is-short .stage-head h1,
  .story-stage.is-short .stage-head h2 { font-size: 1.55rem; }
  .story-stage.is-tight .say-sub { display: none; }
  .story-stage.is-tight .say-line { margin-bottom: 0; }

  /* 설명 칸은 판의 폭을 다 쓴다. 가운데 놓인 채 «제 글만큼» 줄어들어 있었는데
     (justify-items:center), 그러면 가장 긴 줄이 칸에 꼭 맞게 서서 아이폰에서는
     반 픽셀이 모자라 끝 어절이 내려가고, text-wrap:pretty 가 그 한 어절을
     외롭지 않게 하려고 앞의 것까지 끌어내렸다 — 「행정 · 쇼핑 · 건강 · 교육」
     다음 줄이 「· 관심사 가운데」 로 시작했다. 두 줄이 석 줄이 되어 폰의 키도
     26px 을 잃었다. 글은 그대로 가운데 정렬이라 보이는 자리는 같다. */
  .story-stage .stage-say { justify-self: stretch; }

  /* 설명과 걸음표가 붙어 보였다 (2026-10-08). 사이는 12px 로 적혀 있지만 설명 칸이 Z 로
     34px 앞에 나와 있어 원근이 아래쪽을 5px 쯤 밀어낸다 — 잰 값이 걸음마다 2.5~9px
     (마이디 04 · 06 이 2.5~3px). 그만큼을 걸음표 위에 돌려준다. */
  .stage-steps { margin-top: 6px; }
}

/* ── 아래 띠가 글을 덮던 것 (2026-10-06) ─────────────────────────────
   「마이디 받기」 띠는 fixed 라 자리를 차지하지 않는다. 그래서 쪽 맨 끝의
   글이 그 밑으로 들어갔다 — 마이주식 · 마이디 · 연결 · SNP Brain · FL-STUDIO
   다섯 쪽에서 마지막 문단이 띠에 가려 있었다.
   띠는 bottom:14 에 높이 50 이므로 바닥에서 64px 을 차지한다. 숨 쉴 자리까지
   78px 을 비운다. 아이폰 홈 바가 있는 기기는 safe-area 만큼 더 비운다.
   띠가 없는 시작하기.html 에는 걸리지 않게 :has 로 가린다 — 지원하지 않는
   브라우저에서는 규칙이 통째로 무시되고, 그때는 예전과 같은 상태다.       */
@media (max-width: 760px) {
  body:has(.mobile-beta) { padding-bottom: calc(78px + env(safe-area-inset-bottom, 0px)); }
}

/* ── 받기 단추의 스토어 로고 (2026-10-08) ─────────────────────────────
   Google Play · App Store · ONE store 로 가는 받기 단추 열다섯(인덱스 5 ·
   마이디 2 · 마이주식 3 · 고객 서비스 5)의 글씨 앞에 그 가게의 로고를 둔다.
   단추의 꼴 · 색 · 높이는 그대로다 — 로고 20px 와 사이 8px 만큼 폭만 는다.

   마크업이 아니라 ::before 로 넣는 까닭 — 이 단추들은 data-en 이 «안» 을 통째로
   갈아 끼운다. 안에 <img> 를 넣으면 영문으로 바꾸는 순간 사라지고, 두 언어에
   한 벌씩 서른 자리에 적어야 한다. 주소(href)로 가게를 가리면 한 번이면 된다.
   하단 띠와 바닥글의 가게 링크는 .btn 이 아니라 걸리지 않는다.

   z-index 를 주는 까닭 — 파문(.ink)이 z-index 0 으로 깔리고 글자는 861행이
   그 위로 올린다. ::before 는 「> *」 에 잡히지 않아 따로 올려야 한다.

   로고의 출처 — Google Play: play.google.com 의 4색 아이콘 · Apple: Simple
   Icons(CC0) · ONE store: onestore.co.kr 의 심볼(52px, 20px 로 그려 2.6배).   */
.btn[href*="play.google.com"]::before,
.btn[href*="apps.apple.com"]::before,
.btn[href*="onestore.co.kr"]::before {
  content: ""; flex: none; position: relative; z-index: 1;
  width: 1.25em; height: 1.25em;
  background: center / contain no-repeat;
}
.btn[href*="play.google.com"]::before { background-image: url(brand/store-google-play.svg); }
.btn[href*="apps.apple.com"]::before { background-image: url(brand/store-apple.svg); }
.btn[href*="onestore.co.kr"]::before { background-image: url(brand/store-onestore.png); }

/* 휴대폰에서는 로고를 넣기 전과 같은 줄에 선다 (2026-10-08).
   로고(20 + 사이 8 = 28px)만큼 단추가 넓어져, 375px 인덱스에서 두 개씩 앉던 단추가
   한 줄에 하나씩 내려갔다 — 마이주식 칸은 두 줄(108px)이 네 줄(227px)이 됐다.
   그 28px 을 단추 안에서 되찾는다:
     화살표 ↗ 를 걷는다          14.5 - 3.2(제 음수 여백) + 사이 8 = 19.3px
     좌우 안여백을 4px 씩 줄인다                                    =  8.0px
     로고와 글씨 사이를 1px 당긴다                                 =  1.0px
   합 28.3px — 로고를 넣기 전보다 0.3px 좁아, 접히는 자리가 그대로다. 마지막
   1px 이 없으면 0.7px 이 남는데, 375px 고객 서비스의 마이주식 카드가 꼭 그만큼
   모자라 App Store 와 ONE store 가 갈라섰다(131.6 + 10 + 131.6 > 칸 272).
   화살표는 「새 창」 표시인데 휴대폰에서는 가게 앱이 열리고, 낭독기가 읽는
   「(새 창)」 글자는 그대로 남는다. 761px 부터는 화살표도 여백도 전과 같다.
   인덱스 칸은 제 인라인 규칙이 이미 14px 로 줄여 두었으므로(.flow-cta-acts .btn)
   거기서 4px 을 더 뺀 10px 을 한 겹 더 무겁게 적는다. */
@media (max-width: 760px) {
  .btn[href*="play.google.com"] .ar-ne,
  .btn[href*="apps.apple.com"] .ar-ne,
  .btn[href*="onestore.co.kr"] .ar-ne { display: none; }
  .btn[href*="play.google.com"]::before,
  .btn[href*="apps.apple.com"]::before,
  .btn[href*="onestore.co.kr"]::before { margin-right: -1px; }
  .btn[href*="play.google.com"],
  .btn[href*="apps.apple.com"],
  .btn[href*="onestore.co.kr"] { padding-left: 14px; padding-right: 14px; }
  .flow-cta-acts .btn[href*="play.google.com"],
  .flow-cta-acts .btn[href*="apps.apple.com"],
  .flow-cta-acts .btn[href*="onestore.co.kr"] { padding-left: 10px; padding-right: 10px; }
}
/* 2026-10-12 아래 두 칸 규칙은 344px 부터만 건다(인덱스 받기 칸과 같은 경계).
   320px 에서는 반 칸이 124px 인데 Google Play 단추의 알맹이가 132px 이라, 로고와 글씨가
   단추 가장자리 5px 까지 붙었다(App Store 11.7px · 360px 의 Google Play 15.1px).
   그보다 좁은 폰은 전처럼 한 줄에 하나씩 선다(.page-hero .actions .btn 의 width:100%). */
@media (min-width: 344px) and (max-width: 760px) {
  /* 제품 쪽 제목 화면(.page-hero)에서도 둘씩 한 줄 (2026-10-08).
     346행의 width:100% 가 받기 단추까지 한 줄에 하나씩 세워, 마이디 · 마이주식의
     단추 셋이 세 줄(173px)로 쌓였다 — 바로 아래 고정 띠에서는 두 가게가 한 줄이다.
     가게 단추만 반 칸(사이 12px 의 절반을 뺀다)으로 좁혀 Google Play 와 App Store
     가 한 줄에 서고, 셋째(myd.world · ONE store)는 다음 줄로 간다.
     단추의 꼴 · 색 · 로고 · 높이(49.6px)는 그대로이고 자리만 바뀐다.
     nowrap 을 함께 적는 까닭 — Google Play 단추는 제 폭이 143.9px 인데 360px 판의
     반 칸이 144px 이라 0.1px 차이로 든다. 359px 부터는 글씨가 「Google / Play」 두
     줄로 꺾여 단추 키가 달라진다. 한 줄로 못박으면 모자란 만큼은 좌우 안여백이
     받아 준다(가운데 정렬이라 양쪽으로 고르게 — 344px 에서 11px 씩 남는다). */
  .page-hero .actions .btn[href*="play.google.com"],
  .page-hero .actions .btn[href*="apps.apple.com"],
  .page-hero .actions .btn[href*="onestore.co.kr"] { width: calc(50% - 6px); white-space: nowrap; }
}

/* ── 휴대폰의 펼친 메뉴가 화면보다 길었다 (2026-10-08) ─────────────────
   서랍(.site-nav)은 머리띠 아래에 절대 자리로 붙는데 키에 한도가 없었다.
   링크 스물둘에 995px 을 쓰는데 화면은 780px(360폰) · 844px(390폰)이고,
   머리띠가 붙박이라 쪽을 굴려도 서랍은 따라 올라오지 않는다 — 「문의 · 안내」
   와 그 세부탭 넷이 화면 아래로 나가 아예 닿을 수 없었다(568px 화면에서는
   「기업 솔루션」 부터). 스물한 쪽 · 두 언어 · 네 폭 모두에서 그랬다.
     서랍의 키를 «화면 - 머리띠» 로 묶고 그 안에서 굴린다. 100dvh 는 주소창이
     오르내릴 때의 실제 높이다 — 모르는 브라우저는 앞줄의 100vh 를 쓴다.
     contain 은 서랍 끝에서 뒤의 쪽이 따라 구르지 않게 한다.
   맨 아래 여백을 넉넉히 둔 까닭 — 끝까지 굴렸을 때 마지막 줄이 화면
   가장자리(와 아이폰 홈 바)에 붙지 않게.
   --hd 는 app.js 가 재어 넣는 머리띠 높이다(없으면 77px). */
@media (max-width: 760px) {
  .site-header .site-nav {
    max-height: calc(100vh - var(--hd, 77px));
    max-height: calc(100dvh - var(--hd, 77px));
    overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
    padding-bottom: calc(28px + env(safe-area-inset-bottom, 0px));
  }
}

/* ── 입력칸보다 긴 안내 글은 말줄임으로 끝낸다 (2026-10-08) ──────────────
   문의 서식의 영문 안내 글 「Leave blank if you are an individual」 이 360px 칸에서
   「…an indiv」 로 글자 한가운데서 뚝 끊겼다. 칸을 채우기 시작하면 사라지는 글이라
   줄이지 않고, 잘리는 자리에 … 을 찍는다. 채운 글에는 걸리지 않는다. */
.form-field input:placeholder-shown { text-overflow: ellipsis; }

/* ── 낮은 화면에서 펼침 메뉴를 두 단으로 (2026-10-13) ─────────────────
   가로로 눕힌 휴대폰(폭 761 이상 · 높이 380 이하)에서 「기업 솔루션」 의
   마지막 항목이 화면 아래로 나갔다. 셈 — 목록은 y=92 에서 시작하고 여섯 칸 ×
   44 + 틈 5 × 2 = 274 라 아래끝이 366 이다. 높이 366 에서 바닥에 딱 닿고,
   그보다 낮으면 「Bar Code System」 이 잘린다. 가로 폰은 주소창까지 먹어
   보이는 높이가 330 안팎이라 흔히 걸린다.
     칸을 줄이지 않는다 — 44 는 손가락이 닿을 최소 크기다(위 1735행).
     안에서 굴리게 하지도 않는다 — 머리띠 밑 좁은 판을 손가락으로 굴리기는 어렵다.
     세 줄씩 «두 단» 으로 편다. 위에서 아래로 먼저 읽히게(column) 둔다 —
     목록 차례가 그대로 남는다. 가장 긴 목록(여섯)이 3 줄 × 44 + 틈 = 136 이라
     아래끝이 228 로 올라온다. 높이 240 까지 버틴다.
   판(::after)의 높이도 --nav-list-h 를 따르므로 함께 줄어든다(304 → 166).
   확인: 844x366 · 761x300 에서 메뉴 넷 모두 아래끝 228, 오른끝 596 이하.  */
@media (min-width: 761px) and (max-height: 380px) {
  .site-header { --nav-list-h: 136px; }
  .site-header .nav-menu { grid-auto-flow: column; grid-template-rows: repeat(3, auto); column-gap: 32px; }
}
