/* ── 서체 — 디자이너 시안의 A2Z(에이투지체). 공개 폰트, 상업적 사용 허용 ──────
   시안이 쓰는 웨이트 셋만 넣습니다(4 Regular · 5 Medium · 7 Bold = 447KB).
   원본 파일명이 한글이라 URL 인코딩 사고를 피하려고 ASCII 로 바꿔 두었습니다.
   swap — 폰트를 기다리며 글자가 안 보이는 구간을 만들지 않습니다 */
/* ── 서체 — 2단 구성 (2026-09-15) ────────────────────────────────────────
   ★ 세 벌 합쳐 **447KB -> 55.9KB** 입니다(웨이트당 158/131/158 -> 각 18.6KB).
     설득 영역 4화면(랜딩·로그인·가입·404)이 실제로 쓰는 **333자**만 남긴 서브셋입니다.

   ★ **왜 원본을 같이 두나 — 카피가 바뀌어도 안 깨지게 하려고입니다.**
     아래처럼 `원본 먼저 · 서브셋 나중`으로 선언하면, 같은 글자에 대해 **뒤에 선언된
     쪽이 이깁니다**. 서브셋에는 unicode-range 가 달려 있어 **그 333자에서만** 이기고,
     범위 밖 글자(새 문구·새 섹션)는 원본이 받습니다.
     정적 서브셋만 두면 그런 글자가 **폴백 글꼴로 나와 한 문장 안에서 서체가 섞입니다**.

   ★ 평소에는 원본을 **안 받습니다** — 브라우저는 실제로 쓰이는 face 만 내려받습니다.
     범위 밖 글자가 한 자라도 나오는 페이지에서만 그 웨이트의 원본(약 158KB)이 추가됩니다.

   ★ 다시 만들려면 (카피가 크게 바뀐 뒤 서브셋을 좁히고 싶을 때):
       디자이너가 준 원본 서체(저장소 밖) + `pip install fonttools brotli`
       python -m fontTools.subset <원본> --text-file=<쓰는 글자> --flavor=woff2
         --layout-features='*' --output-file=site/assets/fonts/a2z-<웨이트>-sub.woff2
   ★ preload 도 서브셋을 가리켜야 합니다 — 4화면 전부(index·login·signup·404) */

/* ① 원본 — 대체본입니다. **서브셋의 여집합**만 덮습니다.
   ★ 처음엔 unicode-range 없이(= 전 범위) 뒀는데, 그러면 같은 글자를 두 face 가
     같이 덮어 **크롬이 원본 700(158KB)까지 받아 왔습니다**(실측). 겹치지 않게
     갈라 두면 서브셋에 있는 글자는 원본을 아예 건드리지 않습니다 */
@font-face{font-family:"A2Z";src:url("../fonts/a2z-400.woff2") format("woff2");
  font-weight:400;font-style:normal;font-display:swap;unicode-range:U+0000-001F,U+007F-00A8,U+00AA-00AD,U+00AF,U+00B2-00B4,U+00B6,U+00B8-00D6,U+00D8-00F6,U+00F8-03A8,U+03AA-03BB,U+03BD-2012,U+2015-2017,U+201A-201B,U+201E-2025,U+2027-2102,U+2104-2115,U+2117-2121,U+2123-218F,U+2194-2219,U+221B-221D,U+221F-225F,U+2261-2263,U+2266-245F,U+2463-2714,U+2716-3007,U+300A-300B,U+3010-338E,U+3390-3395,U+3397-339B,U+339E-ABFF,U+AC02-AC03,U+AC05-AC07,U+AC09-AC11,U+AC13-AC1B,U+AC1D-AC6F,U+AC71-AC73,U+AC75-AC7F,U+AC81-AC8B,U+AC8D-ACAF,U+ACB1-ACBC,U+ACBE-ACC3,U+ACC5-ACDF,U+ACE2-ACFB,U+ACFD-ACFF,U+AD01-AD10,U+AD12-AD4F,U+AD51-AD6B,U+AD6D-ADA3,U+ADA5-ADDF,U+ADE1-ADF7,U+ADF9-ADFB,U+ADFD-AE08,U+AE0A-AE2F,U+AE31-AE37,U+AE39-AE4B,U+AE4D-AED7,U+AED9-B00B,U+B00D-B097,U+B099-B0AD,U+B0AF-B0B3,U+B0B5-B0C4,U+B0C6-B18C,U+B18E-B191,U+B193-B203,U+B205-B207,U+B209-B293,U+B295-B2A4,U+B2A6-B2C7,U+B2C9-B2E3,U+B2E5-B2E7,U+B2E9-B2EA,U+B2ED-B2F3,U+B2F5-B2FF,U+B301-B377,U+B379-B3C3,U+B3C6-B3D8,U+B3DA-B417,U+B419-B41B,U+B41D-B428,U+B42A-B44F,U+B451-B4A3,U+B4A5-B4DB,U+B4DD-B4EC,U+B4EE-B4F0,U+B4F2-B513,U+B515-B52F,U+B531-B77B,U+B77D-B78B,U+B78D-B7C8,U+B7CA-B824,U+B826-B85B,U+B85E-B8CB,U+B8CD-B957,U+B959-B973,U+B975-B977,U+B979-B97B,U+B97D-B983,U+B985-B9AB,U+B9AD-B9BC,U+B9BE-B9C7,U+B9C9-B9CB,U+B9CD-BA73,U+BA75-BA84,U+BA86-BAA7,U+BAA9-BB37,U+BB39-BB3B,U+BB3D-BBF7,U+BBF9-BBFF,U+BC01-BC13,U+BC15-BC1C,U+BC1E-BC28,U+BC2A-BC2F,U+BC31-BC83,U+BC85-BC87,U+BC89-BC94,U+BC96-BCBF,U+BCC1-BCC3,U+BCC5-BCF3,U+BCF6-BD7F,U+BD81-BD83,U+BD85-BE43,U+BE45-C0AB,U+C0AD-C0AF,U+C0B1-C0C0,U+C0C2-C0C7,U+C0CA-C0D7,U+C0D9-C0DC,U+C0DE-C11B,U+C11E-C11F,U+C121-C123,U+C125-C130,U+C132-C137,U+C139-C13B,U+C13D-C18B,U+C18E-C217,U+C219-C21F,U+C221-C2A3,U+C2A5-C2B4,U+C2B6-C2DB,U+C2DE-C2DF,U+C2E1-C2E3,U+C2E5-C528,U+C52A-C543,U+C545-C547,U+C549-C57B,U+C57D-C5B3,U+C5B5-C5C4,U+C5C7,U+C5C9-C5CF,U+C5D1-C5EB,U+C5ED-C5EF,U+C5F1-C5F3,U+C5F5-C600,U+C602-C607,U+C609-C62B,U+C62D-C63F,U+C641-C677,U+C679-C693,U+C695-C6A8,U+C6AA-C6B3,U+C6B5-C6BF,U+C6C1-C6CF,U+C6D1-C71F,U+C722-C727,U+C729-C73B,U+C73D-C73F,U+C741-C743,U+C745-C74B,U+C74D-C757,U+C759-C773,U+C775-C777,U+C779-C77B,U+C77D-C784,U+C786-C787,U+C789-C78F,U+C792-C7A0,U+C7A2-C7A4,U+C7A6-C7AB,U+C7AD-C7FF,U+C802-C803,U+C805-C807,U+C809-C80F,U+C811-C814,U+C816-C81B,U+C81D-C86F,U+C872-C873,U+C875-C884,U+C886-C8FB,U+C8FD-C8FF,U+C901-C99C,U+C99E-C9BF,U+C9C2-C9C3,U+C9C5-C9C7,U+C9C9-CC0C,U+CC0E-CC27,U+CC29-CC3D,U+CC3F-CC97,U+CC99-CC9B,U+CC9D-CCB3,U+CCB5-CD07,U+CD09-CD1C,U+CD1E-CD2B,U+CD2D-CD93,U+CD96-CD9B,U+CD9D-CDA8,U+CDAA-CE20,U+CE22-CE57,U+CE59-CE67,U+CE69-CE7B,U+CE7D-D06B,U+D06D-D0D4,U+D0D6-D0DB,U+D0DD-D12F,U+D131-D2B7,U+D2BA-D2BB,U+D2BD-D30F,U+D311-D37B,U+D37D-D397,U+D399-D3C8,U+D3CA-D3EB,U+D3EE-D45B,U+D45D-D487,U+D489-D50B,U+D50D-D543,U+D545-D557,U+D55A-D55B,U+D55D-D55F,U+D561-D567,U+D56A-D573,U+D575-D588,U+D58A-D603,U+D605-D637,U+D639-D653,U+D656-D65B,U+D65D-D68B,U+D68D-D6C3,U+D6C5-D74F,U+D751-D787,U+D789-10FFFF}
@font-face{font-family:"A2Z";src:url("../fonts/a2z-500.woff2") format("woff2");
  font-weight:500;font-style:normal;font-display:swap;unicode-range:U+0000-001F,U+007F-00A8,U+00AA-00AD,U+00AF,U+00B2-00B4,U+00B6,U+00B8-00D6,U+00D8-00F6,U+00F8-03A8,U+03AA-03BB,U+03BD-2012,U+2015-2017,U+201A-201B,U+201E-2025,U+2027-2102,U+2104-2115,U+2117-2121,U+2123-218F,U+2194-2219,U+221B-221D,U+221F-225F,U+2261-2263,U+2266-245F,U+2463-2714,U+2716-3007,U+300A-300B,U+3010-338E,U+3390-3395,U+3397-339B,U+339E-ABFF,U+AC02-AC03,U+AC05-AC07,U+AC09-AC11,U+AC13-AC1B,U+AC1D-AC6F,U+AC71-AC73,U+AC75-AC7F,U+AC81-AC8B,U+AC8D-ACAF,U+ACB1-ACBC,U+ACBE-ACC3,U+ACC5-ACDF,U+ACE2-ACFB,U+ACFD-ACFF,U+AD01-AD10,U+AD12-AD4F,U+AD51-AD6B,U+AD6D-ADA3,U+ADA5-ADDF,U+ADE1-ADF7,U+ADF9-ADFB,U+ADFD-AE08,U+AE0A-AE2F,U+AE31-AE37,U+AE39-AE4B,U+AE4D-AED7,U+AED9-B00B,U+B00D-B097,U+B099-B0AD,U+B0AF-B0B3,U+B0B5-B0C4,U+B0C6-B18C,U+B18E-B191,U+B193-B203,U+B205-B207,U+B209-B293,U+B295-B2A4,U+B2A6-B2C7,U+B2C9-B2E3,U+B2E5-B2E7,U+B2E9-B2EA,U+B2ED-B2F3,U+B2F5-B2FF,U+B301-B377,U+B379-B3C3,U+B3C6-B3D8,U+B3DA-B417,U+B419-B41B,U+B41D-B428,U+B42A-B44F,U+B451-B4A3,U+B4A5-B4DB,U+B4DD-B4EC,U+B4EE-B4F0,U+B4F2-B513,U+B515-B52F,U+B531-B77B,U+B77D-B78B,U+B78D-B7C8,U+B7CA-B824,U+B826-B85B,U+B85E-B8CB,U+B8CD-B957,U+B959-B973,U+B975-B977,U+B979-B97B,U+B97D-B983,U+B985-B9AB,U+B9AD-B9BC,U+B9BE-B9C7,U+B9C9-B9CB,U+B9CD-BA73,U+BA75-BA84,U+BA86-BAA7,U+BAA9-BB37,U+BB39-BB3B,U+BB3D-BBF7,U+BBF9-BBFF,U+BC01-BC13,U+BC15-BC1C,U+BC1E-BC28,U+BC2A-BC2F,U+BC31-BC83,U+BC85-BC87,U+BC89-BC94,U+BC96-BCBF,U+BCC1-BCC3,U+BCC5-BCF3,U+BCF6-BD7F,U+BD81-BD83,U+BD85-BE43,U+BE45-C0AB,U+C0AD-C0AF,U+C0B1-C0C0,U+C0C2-C0C7,U+C0CA-C0D7,U+C0D9-C0DC,U+C0DE-C11B,U+C11E-C11F,U+C121-C123,U+C125-C130,U+C132-C137,U+C139-C13B,U+C13D-C18B,U+C18E-C217,U+C219-C21F,U+C221-C2A3,U+C2A5-C2B4,U+C2B6-C2DB,U+C2DE-C2DF,U+C2E1-C2E3,U+C2E5-C528,U+C52A-C543,U+C545-C547,U+C549-C57B,U+C57D-C5B3,U+C5B5-C5C4,U+C5C7,U+C5C9-C5CF,U+C5D1-C5EB,U+C5ED-C5EF,U+C5F1-C5F3,U+C5F5-C600,U+C602-C607,U+C609-C62B,U+C62D-C63F,U+C641-C677,U+C679-C693,U+C695-C6A8,U+C6AA-C6B3,U+C6B5-C6BF,U+C6C1-C6CF,U+C6D1-C71F,U+C722-C727,U+C729-C73B,U+C73D-C73F,U+C741-C743,U+C745-C74B,U+C74D-C757,U+C759-C773,U+C775-C777,U+C779-C77B,U+C77D-C784,U+C786-C787,U+C789-C78F,U+C792-C7A0,U+C7A2-C7A4,U+C7A6-C7AB,U+C7AD-C7FF,U+C802-C803,U+C805-C807,U+C809-C80F,U+C811-C814,U+C816-C81B,U+C81D-C86F,U+C872-C873,U+C875-C884,U+C886-C8FB,U+C8FD-C8FF,U+C901-C99C,U+C99E-C9BF,U+C9C2-C9C3,U+C9C5-C9C7,U+C9C9-CC0C,U+CC0E-CC27,U+CC29-CC3D,U+CC3F-CC97,U+CC99-CC9B,U+CC9D-CCB3,U+CCB5-CD07,U+CD09-CD1C,U+CD1E-CD2B,U+CD2D-CD93,U+CD96-CD9B,U+CD9D-CDA8,U+CDAA-CE20,U+CE22-CE57,U+CE59-CE67,U+CE69-CE7B,U+CE7D-D06B,U+D06D-D0D4,U+D0D6-D0DB,U+D0DD-D12F,U+D131-D2B7,U+D2BA-D2BB,U+D2BD-D30F,U+D311-D37B,U+D37D-D397,U+D399-D3C8,U+D3CA-D3EB,U+D3EE-D45B,U+D45D-D487,U+D489-D50B,U+D50D-D543,U+D545-D557,U+D55A-D55B,U+D55D-D55F,U+D561-D567,U+D56A-D573,U+D575-D588,U+D58A-D603,U+D605-D637,U+D639-D653,U+D656-D65B,U+D65D-D68B,U+D68D-D6C3,U+D6C5-D74F,U+D751-D787,U+D789-10FFFF}
@font-face{font-family:"A2Z";src:url("../fonts/a2z-700.woff2") format("woff2");
  font-weight:700;font-style:normal;font-display:swap;unicode-range:U+0000-001F,U+007F-00A8,U+00AA-00AD,U+00AF,U+00B2-00B4,U+00B6,U+00B8-00D6,U+00D8-00F6,U+00F8-03A8,U+03AA-03BB,U+03BD-2012,U+2015-2017,U+201A-201B,U+201E-2025,U+2027-2102,U+2104-2115,U+2117-2121,U+2123-218F,U+2194-2219,U+221B-221D,U+221F-225F,U+2261-2263,U+2266-245F,U+2463-2714,U+2716-3007,U+300A-300B,U+3010-338E,U+3390-3395,U+3397-339B,U+339E-ABFF,U+AC02-AC03,U+AC05-AC07,U+AC09-AC11,U+AC13-AC1B,U+AC1D-AC6F,U+AC71-AC73,U+AC75-AC7F,U+AC81-AC8B,U+AC8D-ACAF,U+ACB1-ACBC,U+ACBE-ACC3,U+ACC5-ACDF,U+ACE2-ACFB,U+ACFD-ACFF,U+AD01-AD10,U+AD12-AD4F,U+AD51-AD6B,U+AD6D-ADA3,U+ADA5-ADDF,U+ADE1-ADF7,U+ADF9-ADFB,U+ADFD-AE08,U+AE0A-AE2F,U+AE31-AE37,U+AE39-AE4B,U+AE4D-AED7,U+AED9-B00B,U+B00D-B097,U+B099-B0AD,U+B0AF-B0B3,U+B0B5-B0C4,U+B0C6-B18C,U+B18E-B191,U+B193-B203,U+B205-B207,U+B209-B293,U+B295-B2A4,U+B2A6-B2C7,U+B2C9-B2E3,U+B2E5-B2E7,U+B2E9-B2EA,U+B2ED-B2F3,U+B2F5-B2FF,U+B301-B377,U+B379-B3C3,U+B3C6-B3D8,U+B3DA-B417,U+B419-B41B,U+B41D-B428,U+B42A-B44F,U+B451-B4A3,U+B4A5-B4DB,U+B4DD-B4EC,U+B4EE-B4F0,U+B4F2-B513,U+B515-B52F,U+B531-B77B,U+B77D-B78B,U+B78D-B7C8,U+B7CA-B824,U+B826-B85B,U+B85E-B8CB,U+B8CD-B957,U+B959-B973,U+B975-B977,U+B979-B97B,U+B97D-B983,U+B985-B9AB,U+B9AD-B9BC,U+B9BE-B9C7,U+B9C9-B9CB,U+B9CD-BA73,U+BA75-BA84,U+BA86-BAA7,U+BAA9-BB37,U+BB39-BB3B,U+BB3D-BBF7,U+BBF9-BBFF,U+BC01-BC13,U+BC15-BC1C,U+BC1E-BC28,U+BC2A-BC2F,U+BC31-BC83,U+BC85-BC87,U+BC89-BC94,U+BC96-BCBF,U+BCC1-BCC3,U+BCC5-BCF3,U+BCF6-BD7F,U+BD81-BD83,U+BD85-BE43,U+BE45-C0AB,U+C0AD-C0AF,U+C0B1-C0C0,U+C0C2-C0C7,U+C0CA-C0D7,U+C0D9-C0DC,U+C0DE-C11B,U+C11E-C11F,U+C121-C123,U+C125-C130,U+C132-C137,U+C139-C13B,U+C13D-C18B,U+C18E-C217,U+C219-C21F,U+C221-C2A3,U+C2A5-C2B4,U+C2B6-C2DB,U+C2DE-C2DF,U+C2E1-C2E3,U+C2E5-C528,U+C52A-C543,U+C545-C547,U+C549-C57B,U+C57D-C5B3,U+C5B5-C5C4,U+C5C7,U+C5C9-C5CF,U+C5D1-C5EB,U+C5ED-C5EF,U+C5F1-C5F3,U+C5F5-C600,U+C602-C607,U+C609-C62B,U+C62D-C63F,U+C641-C677,U+C679-C693,U+C695-C6A8,U+C6AA-C6B3,U+C6B5-C6BF,U+C6C1-C6CF,U+C6D1-C71F,U+C722-C727,U+C729-C73B,U+C73D-C73F,U+C741-C743,U+C745-C74B,U+C74D-C757,U+C759-C773,U+C775-C777,U+C779-C77B,U+C77D-C784,U+C786-C787,U+C789-C78F,U+C792-C7A0,U+C7A2-C7A4,U+C7A6-C7AB,U+C7AD-C7FF,U+C802-C803,U+C805-C807,U+C809-C80F,U+C811-C814,U+C816-C81B,U+C81D-C86F,U+C872-C873,U+C875-C884,U+C886-C8FB,U+C8FD-C8FF,U+C901-C99C,U+C99E-C9BF,U+C9C2-C9C3,U+C9C5-C9C7,U+C9C9-CC0C,U+CC0E-CC27,U+CC29-CC3D,U+CC3F-CC97,U+CC99-CC9B,U+CC9D-CCB3,U+CCB5-CD07,U+CD09-CD1C,U+CD1E-CD2B,U+CD2D-CD93,U+CD96-CD9B,U+CD9D-CDA8,U+CDAA-CE20,U+CE22-CE57,U+CE59-CE67,U+CE69-CE7B,U+CE7D-D06B,U+D06D-D0D4,U+D0D6-D0DB,U+D0DD-D12F,U+D131-D2B7,U+D2BA-D2BB,U+D2BD-D30F,U+D311-D37B,U+D37D-D397,U+D399-D3C8,U+D3CA-D3EB,U+D3EE-D45B,U+D45D-D487,U+D489-D50B,U+D50D-D543,U+D545-D557,U+D55A-D55B,U+D55D-D55F,U+D561-D567,U+D56A-D573,U+D575-D588,U+D58A-D603,U+D605-D637,U+D639-D653,U+D656-D65B,U+D65D-D68B,U+D68D-D6C3,U+D6C5-D74F,U+D751-D787,U+D789-10FFFF}

/* ② 서브셋 — **뒤에 선언해야 합니다.** 같은 글자면 뒤가 이깁니다 */
@font-face{font-family:"A2Z";src:url("../fonts/a2z-400-sub.woff2") format("woff2");
  font-weight:400;font-style:normal;font-display:swap;unicode-range:U+0020-007E,U+00A9,U+00AE,U+00B0-00B1,U+00B5,U+00B7,U+00D7,U+00F7,U+03A9,U+03BC,U+2013-2014,U+2018-2019,U+201C-201D,U+2026,U+2103,U+2116,U+2122,U+2190-2193,U+221A,U+221E,U+2260,U+2264-2265,U+2460-2462,U+2715,U+3008-3009,U+300C-300F,U+338F,U+3396,U+339C-339D,U+AC00-AC01,U+AC04,U+AC08,U+AC12,U+AC1C,U+AC70,U+AC74,U+AC80,U+AC8C,U+ACB0,U+ACBD,U+ACC4,U+ACE0-ACE1,U+ACFC,U+AD00,U+AD11,U+AD50,U+AD6C,U+ADA4,U+ADE0,U+ADF8,U+ADFC,U+AE09,U+AE30,U+AE38,U+AE4C,U+AED8,U+B00C,U+B098,U+B0AE,U+B0B4,U+B0C5,U+B18D,U+B192,U+B204,U+B208,U+B294,U+B2A5,U+B2C8,U+B2E4,U+B2E8,U+B2EB-B2EC,U+B2F4,U+B300,U+B378,U+B3C4-B3C5,U+B3D9,U+B418,U+B41C,U+B429,U+B450,U+B4A4,U+B4DC,U+B4ED,U+B4F1,U+B514,U+B530,U+B77C,U+B78C,U+B7C9,U+B825,U+B85C-B85D,U+B8CC,U+B958,U+B974,U+B978,U+B97C,U+B984,U+B9AC,U+B9BD,U+B9C8,U+B9CC,U+BA74,U+BA85,U+BAA8,U+BB38,U+BB3C,U+BBF8,U+BC00,U+BC14,U+BC1D,U+BC29,U+BC30,U+BC84,U+BC88,U+BC95,U+BCC0,U+BCC4,U+BCF4-BCF5,U+BD80,U+BD84,U+BE44,U+C0AC,U+C0B0,U+C0C1,U+C0C8-C0C9,U+C0D8,U+C0DD,U+C11C-C11D,U+C120,U+C124,U+C131,U+C138,U+C13C,U+C18C-C18D,U+C218,U+C220,U+C2A4,U+C2B5,U+C2DC-C2DD,U+C2E0,U+C2E4,U+C529,U+C544,U+C548,U+C57C,U+C5B4,U+C5C5-C5C6,U+C5C8,U+C5D0,U+C5EC,U+C5F0,U+C5F4,U+C601,U+C608,U+C62C,U+C640,U+C678,U+C694,U+C6A9,U+C6B4,U+C6C0,U+C6D0,U+C720-C721,U+C728,U+C73C,U+C740,U+C744,U+C74C,U+C758,U+C774,U+C778,U+C77C,U+C785,U+C788,U+C790-C791,U+C7A1,U+C7A5,U+C7AC,U+C800-C801,U+C804,U+C808,U+C810,U+C815,U+C81C,U+C870-C871,U+C874,U+C885,U+C8FC,U+C900,U+C99D,U+C9C0-C9C1,U+C9C4,U+C9C8,U+CC0D,U+CC28,U+CC3E,U+CC98,U+CC9C,U+CCB4,U+CD08,U+CD1D,U+CD2C,U+CD94-CD95,U+CD9C,U+CDA9,U+CE21,U+CE58,U+CE68,U+CE7C,U+D06C,U+D0D5,U+D0DC,U+D130,U+D2B8-D2B9,U+D2BC,U+D310,U+D37C,U+D398,U+D3C9,U+D3EC-D3ED,U+D45C,U+D488,U+D50C,U+D544,U+D558-D559,U+D55C,U+D560,U+D568-D569,U+D574,U+D589,U+D604,U+D638,U+D654-D655,U+D65C,U+D68C,U+D6C4,U+D750,U+D788}
@font-face{font-family:"A2Z";src:url("../fonts/a2z-500-sub.woff2") format("woff2");
  font-weight:500;font-style:normal;font-display:swap;unicode-range:U+0020-007E,U+00A9,U+00AE,U+00B0-00B1,U+00B5,U+00B7,U+00D7,U+00F7,U+03A9,U+03BC,U+2013-2014,U+2018-2019,U+201C-201D,U+2026,U+2103,U+2116,U+2122,U+2190-2193,U+221A,U+221E,U+2260,U+2264-2265,U+2460-2462,U+2715,U+3008-3009,U+300C-300F,U+338F,U+3396,U+339C-339D,U+AC00-AC01,U+AC04,U+AC08,U+AC12,U+AC1C,U+AC70,U+AC74,U+AC80,U+AC8C,U+ACB0,U+ACBD,U+ACC4,U+ACE0-ACE1,U+ACFC,U+AD00,U+AD11,U+AD50,U+AD6C,U+ADA4,U+ADE0,U+ADF8,U+ADFC,U+AE09,U+AE30,U+AE38,U+AE4C,U+AED8,U+B00C,U+B098,U+B0AE,U+B0B4,U+B0C5,U+B18D,U+B192,U+B204,U+B208,U+B294,U+B2A5,U+B2C8,U+B2E4,U+B2E8,U+B2EB-B2EC,U+B2F4,U+B300,U+B378,U+B3C4-B3C5,U+B3D9,U+B418,U+B41C,U+B429,U+B450,U+B4A4,U+B4DC,U+B4ED,U+B4F1,U+B514,U+B530,U+B77C,U+B78C,U+B7C9,U+B825,U+B85C-B85D,U+B8CC,U+B958,U+B974,U+B978,U+B97C,U+B984,U+B9AC,U+B9BD,U+B9C8,U+B9CC,U+BA74,U+BA85,U+BAA8,U+BB38,U+BB3C,U+BBF8,U+BC00,U+BC14,U+BC1D,U+BC29,U+BC30,U+BC84,U+BC88,U+BC95,U+BCC0,U+BCC4,U+BCF4-BCF5,U+BD80,U+BD84,U+BE44,U+C0AC,U+C0B0,U+C0C1,U+C0C8-C0C9,U+C0D8,U+C0DD,U+C11C-C11D,U+C120,U+C124,U+C131,U+C138,U+C13C,U+C18C-C18D,U+C218,U+C220,U+C2A4,U+C2B5,U+C2DC-C2DD,U+C2E0,U+C2E4,U+C529,U+C544,U+C548,U+C57C,U+C5B4,U+C5C5-C5C6,U+C5C8,U+C5D0,U+C5EC,U+C5F0,U+C5F4,U+C601,U+C608,U+C62C,U+C640,U+C678,U+C694,U+C6A9,U+C6B4,U+C6C0,U+C6D0,U+C720-C721,U+C728,U+C73C,U+C740,U+C744,U+C74C,U+C758,U+C774,U+C778,U+C77C,U+C785,U+C788,U+C790-C791,U+C7A1,U+C7A5,U+C7AC,U+C800-C801,U+C804,U+C808,U+C810,U+C815,U+C81C,U+C870-C871,U+C874,U+C885,U+C8FC,U+C900,U+C99D,U+C9C0-C9C1,U+C9C4,U+C9C8,U+CC0D,U+CC28,U+CC3E,U+CC98,U+CC9C,U+CCB4,U+CD08,U+CD1D,U+CD2C,U+CD94-CD95,U+CD9C,U+CDA9,U+CE21,U+CE58,U+CE68,U+CE7C,U+D06C,U+D0D5,U+D0DC,U+D130,U+D2B8-D2B9,U+D2BC,U+D310,U+D37C,U+D398,U+D3C9,U+D3EC-D3ED,U+D45C,U+D488,U+D50C,U+D544,U+D558-D559,U+D55C,U+D560,U+D568-D569,U+D574,U+D589,U+D604,U+D638,U+D654-D655,U+D65C,U+D68C,U+D6C4,U+D750,U+D788}
@font-face{font-family:"A2Z";src:url("../fonts/a2z-700-sub.woff2") format("woff2");
  font-weight:700;font-style:normal;font-display:swap;unicode-range:U+0020-007E,U+00A9,U+00AE,U+00B0-00B1,U+00B5,U+00B7,U+00D7,U+00F7,U+03A9,U+03BC,U+2013-2014,U+2018-2019,U+201C-201D,U+2026,U+2103,U+2116,U+2122,U+2190-2193,U+221A,U+221E,U+2260,U+2264-2265,U+2460-2462,U+2715,U+3008-3009,U+300C-300F,U+338F,U+3396,U+339C-339D,U+AC00-AC01,U+AC04,U+AC08,U+AC12,U+AC1C,U+AC70,U+AC74,U+AC80,U+AC8C,U+ACB0,U+ACBD,U+ACC4,U+ACE0-ACE1,U+ACFC,U+AD00,U+AD11,U+AD50,U+AD6C,U+ADA4,U+ADE0,U+ADF8,U+ADFC,U+AE09,U+AE30,U+AE38,U+AE4C,U+AED8,U+B00C,U+B098,U+B0AE,U+B0B4,U+B0C5,U+B18D,U+B192,U+B204,U+B208,U+B294,U+B2A5,U+B2C8,U+B2E4,U+B2E8,U+B2EB-B2EC,U+B2F4,U+B300,U+B378,U+B3C4-B3C5,U+B3D9,U+B418,U+B41C,U+B429,U+B450,U+B4A4,U+B4DC,U+B4ED,U+B4F1,U+B514,U+B530,U+B77C,U+B78C,U+B7C9,U+B825,U+B85C-B85D,U+B8CC,U+B958,U+B974,U+B978,U+B97C,U+B984,U+B9AC,U+B9BD,U+B9C8,U+B9CC,U+BA74,U+BA85,U+BAA8,U+BB38,U+BB3C,U+BBF8,U+BC00,U+BC14,U+BC1D,U+BC29,U+BC30,U+BC84,U+BC88,U+BC95,U+BCC0,U+BCC4,U+BCF4-BCF5,U+BD80,U+BD84,U+BE44,U+C0AC,U+C0B0,U+C0C1,U+C0C8-C0C9,U+C0D8,U+C0DD,U+C11C-C11D,U+C120,U+C124,U+C131,U+C138,U+C13C,U+C18C-C18D,U+C218,U+C220,U+C2A4,U+C2B5,U+C2DC-C2DD,U+C2E0,U+C2E4,U+C529,U+C544,U+C548,U+C57C,U+C5B4,U+C5C5-C5C6,U+C5C8,U+C5D0,U+C5EC,U+C5F0,U+C5F4,U+C601,U+C608,U+C62C,U+C640,U+C678,U+C694,U+C6A9,U+C6B4,U+C6C0,U+C6D0,U+C720-C721,U+C728,U+C73C,U+C740,U+C744,U+C74C,U+C758,U+C774,U+C778,U+C77C,U+C785,U+C788,U+C790-C791,U+C7A1,U+C7A5,U+C7AC,U+C800-C801,U+C804,U+C808,U+C810,U+C815,U+C81C,U+C870-C871,U+C874,U+C885,U+C8FC,U+C900,U+C99D,U+C9C0-C9C1,U+C9C4,U+C9C8,U+CC0D,U+CC28,U+CC3E,U+CC98,U+CC9C,U+CCB4,U+CD08,U+CD1D,U+CD2C,U+CD94-CD95,U+CD9C,U+CDA9,U+CE21,U+CE58,U+CE68,U+CE7C,U+D06C,U+D0D5,U+D0DC,U+D130,U+D2B8-D2B9,U+D2BC,U+D310,U+D37C,U+D398,U+D3C9,U+D3EC-D3ED,U+D45C,U+D488,U+D50C,U+D544,U+D558-D559,U+D55C,U+D560,U+D568-D569,U+D574,U+D589,U+D604,U+D638,U+D654-D655,U+D65C,U+D68C,U+D6C4,U+D750,U+D788}

/* ── 작업 영역 서체 — Pretendard (2026-09-15) ────────────────────────────
   ★ **외부 CDN 에서 내렸습니다.** app.html · admin.html 이 jsdelivr 의
     `pretendardvariable-dynamic-subset.min.css` 를 **render-blocking 으로** 불렀고,
     그 CSS 가 다시 woff2 를 끌어오는 요청 연쇄까지 있었습니다(합계 약 204KB).
     `CLAUDE.md` 의 *"빌드 없음 · 프레임워크 없음 · 의존성 없음"* 과 어긋나 있었고,
     랜딩은 A2Z 를 서브셋했는데 **작업 영역만 외부 의존이 남아** 있었습니다.

   원본     Pretendard v1.3.9 가변(PretendardVariable.woff2) 2,009.5 KB
   ~~서브셋 84.8 KB — 작업 영역 두 화면이 쓰는 355자 · 원본 폴백 없음(범위 밖은 맑은 고딕)~~

   ★ 2026-09-17 — **공식 조각 서브셋(dynamic subset) 92개로 바꿨습니다**(사용자 결정).
     우리가 고른 355자 서브셋은 화면 문구에만 맞았습니다. 가입자 이름·이메일처럼 **사람이 입력한 글자**가
     들어오자 계정 화면에서만 19자가 맑은 고딕으로 섞였고, 회원이 늘 때마다 다시 만들어야 하는 구조였습니다.
     조각 방식은 브라우저가 **화면에 나온 글자가 든 조각만** 받습니다 — Pretendard 공식 권장 사용법이고
     Google Fonts 한글(Noto Sans KR)과 같은 방식입니다. **다시 만들 일이 없습니다.**
   @font-face  assets/css/pretendard.css(49.7 KB · 배포판 그대로 · 손으로 안 고침) — app.html · admin.html 만 부릅니다.
               ★ 여기(site.css)에 두지 않습니다 — 랜딩도 site.css 를 받는데 랜딩은 A2Z 라 필요 없습니다
   조각        assets/fonts/pretendard/ 92개(8~44 KB). 실측 — 대시보드 첫 화면 6조각 · 관리 첫 화면 9조각
   preload     두 첫 화면이 **둘 다** 쓰는 82 · 87~91 여섯만(약 155 KB · 실측 Fast 4G 에서 첫 그리기 전에 도착) — 첫 방문에 글꼴이 바뀌어 보이는 것을 줄입니다
   ★ 가변 축이 살아 있어 굵기 다섯(400~800)을 조각 하나가 덮습니다
   라이선스  SIL OFL 1.1 — 자체 호스팅·재배포 허용. 저작권 줄은 pretendard.css 머리에 둡니다 */

:root{
  --sans:"A2Z","Pretendard Variable",Pretendard,-apple-system,"Malgun Gothic","맑은 고딕",sans-serif;
  /* ★ 서체가 두 영역으로 갈립니다 (2026-09-10 사용자 결정) —
     설득 영역(랜딩·로그인·가입·404)은 시안의 A2Z,
     작업 영역(대시보드)은 Pretendard 를 유지합니다.
     다섯 페이지가 site.css 를 다 부르므로 대시보드에서만 되돌립니다 -> body.work */
  --bg:#fff;--surface:#fff;--line:#e5e5e5;--fg:#111;--muted:#666;
  --accent:#000;--on-accent:#fff;--ok:#0a0;--warn:#a80;--bad:#a00;
  --ghost:color-mix(in srgb,var(--muted) 20%, transparent);
  /* 등급 분포 막대의 `부동` 구간 전용 색.
     --ghost(20 %)를 쓰면 어두운 모드에서 바닥과 1.05:1 이라 구간이 사라집니다.
     막대는 장식이 아니라 데이터라 WCAG 1.4.11 의 3:1 을 지켜야 합니다.
     --muted 자체는 두 모드 다 대비가 충분하고, 70 % 로 섞으면
     밝은 모드 3.1:1 · 어두운 모드 3.5:1 이 나옵니다(2026-09-08 측정).
     트랙·바탕에 쓰는 --ghost 와 역할을 나눠 둡니다. */
  --bar-im:color-mix(in srgb,var(--muted) 70%, var(--surface));

  /* ── 디자이너 시안 토큰 (2026-09-10) ─────────────────────────────────
     변수로 정의돼 온 것은 Main/Bule 하나뿐이라 나머지는 시안에서 직접 잰 값입니다. */
  --brand:#0143B7;          /* Main/Bule — 마퀴 밴드 · 지표 띠 · 활성 카드 */
  --brand-2:#005CFF;        /* nav 로그인 버튼 그라디언트의 끝 */
  --violet:#5420FE;         /* 히어로 버튼. 파랑과 다른 색입니다 */
  /* 어두운 섹션 — 시안 값 그대로 씁니다(사용자 결정 A). 섹션마다 다릅니다 */
  --d-hero:#010D28;         /* 히어로 바닥. 영상·포스터가 못 뜨면 이 색이 그대로 보입니다 */
  --d-flow:#000208;         /* 검사 흐름 */
  --d-cta:#01060A;          /* CTA */
  --d-foot:#000000;         /* footer */
  /* 시안의 섹션 제목/부제 색 — 변수 section/title 이 이 둘만 정의합니다.
     전역 --fg · --muted 는 건드리지 않습니다(대시보드가 같이 씁니다) */
  --t-title:#1F1F1F;
  --t-sub:#444444;
  /* 선언이 없으면 삼성 인터넷·크롬 안드로이드가 페이지 색을 스스로 뒤집습니다.
     밝은 배경을 전제로 만든 팔레트라 반전되면 대비가 무너집니다.
     대시보드는 자체 다크 모드가 있어 shell.js 가 여기를 덮어씁니다. */
  color-scheme:light;
}
*{box-sizing:border-box}
/* 화면에서만 감추고 구조는 남깁니다 — 표 머리 · 단계 상태 · 그래프 설명에 씁니다.
   display:none 이나 visibility:hidden 은 보조기술에서도 사라져 쓸 수 없습니다. */
.vh{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;
  overflow:hidden;clip-path:inset(50%);white-space:nowrap}
/* 스크롤 이동은 shell.js 가 굴립니다 */
body{margin:0;background:var(--bg);color:var(--fg);font-family:var(--sans);
  font-size:15.5px;line-height:1.75;-webkit-font-smoothing:antialiased;
  word-break:keep-all;overflow-wrap:break-word;transition:background .25s,color .25s}
h1,h2,h3,h4,p,figure{margin:0}
img,svg{display:block;max-width:100%}
[hidden]{display:none!important}
/* 시안 컨테이너는 1200 입니다. padding 32 를 포함해 1264 로 두면 넓은 폭에서
   내용이 정확히 1200 이 됩니다 (1920 에서 좌우 여백 360, 1440 에서 120) */
/* 작업 영역만 이전 서체로 되돌립니다. body 가 :root 보다 특정도가 높고
   변수는 상속되므로 대시보드 안쪽 전부가 이 값을 씁니다 */
body.work{--sans:"Pretendard Variable",Pretendard,-apple-system,"Malgun Gothic","맑은 고딕",sans-serif}

.wrap{max-width:1264px;margin:0 auto;padding:0 32px}
.wide{max-width:1264px}
@media(max-width:760px){.wrap{padding:0 22px}}

/* 등장 */
.rev{opacity:0;transform:translateY(20px);
  transition:opacity .8s cubic-bezier(.22,.61,.36,1),transform .8s cubic-bezier(.22,.61,.36,1)}
.rev.in{opacity:1;transform:none}
.rev.d1x{transition-delay:.09s}.rev.d2x{transition-delay:.18s}.rev.d3x{transition-delay:.27s}
@media(prefers-reduced-motion:reduce){.rev{opacity:1;transform:none;transition:none}}

/* ── 배경 ────────────────────────────────────────────────────────────
   격자는 히어로에만 둡니다. 페이지 전체에 깔았더니 어디나 같은 바닥이라
   섹션이 서로 구분되지 않고 글자 가독성도 떨어졌습니다 (사용자, 09-07).
   아래 섹션은 흰 바닥(.paper)과 옅은 바닥을 번갈아 써서 갈라 놓습니다.
   body.bgfx 는 랜딩이 아니라 로그인 · 가입 · 404 전용입니다 — 카드 한 장짜리
   화면이라 바닥이 비어 보이는 것을 격자가 채워 줍니다. */
body.bgfx::before{content:"";position:fixed;inset:0;z-index:-1;pointer-events:none;
  background:
    radial-gradient(118% 64% at 50% -14%,
      color-mix(in srgb,var(--accent) 15%, transparent) 0%,
      color-mix(in srgb,var(--accent) 4%, transparent) 44%, transparent 74%),
    linear-gradient(color-mix(in srgb,var(--fg) 4%, transparent) 1px, transparent 1px),
    linear-gradient(90deg, color-mix(in srgb,var(--fg) 4%, transparent) 1px, transparent 1px),
    var(--bg);
  background-size:100% 100%, 100% 48px, 48px 100%}

/* ── 히어로 ── */
.hero-wrap{position:relative;z-index:1}
/* ── 히어로 — 디자이너 시안 (2026-09-10) ────────────────────────────────
   배경은 영상입니다. ~~캔버스~~ 는 2026-09-11 에 폐기했습니다
   파일은 site/assets/video/ 에 있고, 어느 것을 받을지는 landing.js 가 정합니다
   ~~격자 + 흰색으로 녹아드는 그라디언트(09-07)~~ -> 시안이 어두운 히어로라 제거 */
.heroblock{position:relative;overflow:hidden;color:#fff;
  /* ★ 2026-09-15 — 포스터를 **기본 상태에서 내렸습니다**(사용자 지적).
     ~~포스터(영상의 0프레임)를 깔고 그 위로 영상이 페이드~~ 였는데, 정지 그림을 먼저
     읽고 나면 **움직임이 시작되는 순간**이 툭 튑니다. 페이드를 부드럽게 해도 안 없어집니다 —
     튀는 것은 밝기가 아니라 `정지 -> 운동` 이라는 상태 변화이기 때문입니다.
     이제 기본이 어두운 바닥이고, 여기서 영상이 천천히 올라옵니다. 페이드 자체가 움직임입니다 */
  background-color:var(--d-hero);
  background-size:cover;background-position:center;background-repeat:no-repeat}
/* ★ 포스터는 지운 것이 아니라 **대체본으로 내려간 것**입니다. landing.js 가 대체 경로에서만
   깔아 줍니다 — 움직임 줄이기 · 자동재생 차단 · 로드 실패 · 너무 느림.
   JS 가 아예 안 도는 경우는 index.html 의 <noscript> 가 받습니다.
   ★ 2026-09-15 두 번째 수정 — 처음엔 **반대로** 짰습니다(기본값이 포스터 · JS 가 치움).
     저사양에서 **첫 페인트가 그 JS 보다 빨라** 포스터가 번쩍 보였다 사라졌습니다
     (사용자 관찰 · 실제 크롬 CPU 6x 에서 FCP 796ms vs 클래스 1147ms).
     기본값에 그림을 두면 그림이 언제 그려질지는 우리가 정하지 못합니다 */
.heroblock.hero-still{background-image:url(../img/hero-poster.webp)}
.hero-wrap{position:relative;z-index:1}
/* ★ 2026-09-15 — 히어로만 등장 간격을 키웁니다 (사용자 지적: 한꺼번에 뜬다).
   본문 섹션의 .09s 를 그대로 쓰면 **0.8초 전환에 겹침이 90 %** 라 동시로 읽힙니다.
   여기만 .16s 씩 물려, h1 -> 지표 -> 문장 -> 버튼이 차례로 옵니다(끝까지 1.28초).
   .09s 를 전역에서 키우지 않는 이유 — 본문은 한 화면에 한두 덩이만 들어와서
   지금 간격으로 충분하고, 늘리면 스크롤을 따라가는 등장이 늦게 느껴집니다.
   ★ 특정도 0,4,0 으로 .rev.d1x(0,2,0)를 확실히 이깁니다 — 파일 순서에 안 기댑니다.
   ★ 움직임 줄이기에서는 위 .rev 규칙의 transition:none 이 그대로 이깁니다
     (여기서는 transition-delay 만 건드립니다) */
.hero-in .rev.d1x{transition-delay:.16s}
.hero-in .rev.d2x{transition-delay:.32s}
.hero-in .rev.d3x{transition-delay:.48s}
/* 영상은 바닥 위 · 글자 아래. 영상이 못 뜨면 포스터가, 그것도 못 뜨면 --d-hero 가 남습니다 */
.hero-vid{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  z-index:0;pointer-events:none;
  /* 0 에서 시작해 **끊김 없이 갈 만큼 받은 뒤**에 켭니다(landing.js).
     ★ .6s ease 였습니다 — 어두운 바닥에서 올라오는 지금은 이 페이드가 등장 그 자체라
       더 길게 끕니다. ease-in-out 인 이유는 **앞이 느려야** 첫 움직임이 덮이기
       때문입니다(ease-out 은 앞이 빨라 움직임이 바로 드러납니다) */
  opacity:0;transition:opacity 1.2s ease-in-out}
.hero-vid.on{opacity:1}
@media(prefers-reduced-motion:reduce){.hero-vid{transition:none}}

/* ── 이름 띠(마퀴) — 시안 신규 (2026-09-10) ─────────────────────────────
   시안에서는 글자가 프레임보다 넓습니다(2,229 > 1,920). 가로로 흐르라는 뜻입니다.
   같은 묶음을 둘 두고 -50 % 만큼 밀면 이음매 없이 반복됩니다.
   높이 206 · 글자 100 은 1920 기준의 상한이고 좁은 폭에서는 줄입니다(반응형 원칙 ③) */
.mq{overflow:hidden;background:var(--brand);color:#fff;
  height:clamp(96px,10.7vw,206px);display:flex;align-items:center;
  /* ★ 장식이라 선택하지 않습니다. 움직이는 글자를 드래그하면 선택이 계속 따라다녀
     커서가 드래그 상태에 갇힙니다(09-10 사용자 지적) */
  user-select:none;-webkit-user-select:none;cursor:default}
/* ★ 간격을 gap 으로 주면 안 됩니다 — 전체 폭이 Nw+(N-1)g 라 그 -50 % 가
   한 벌의 실제 폭(N/2·w + (N/2-1)·g)과 0.5g 만큼 어긋나 한 바퀴마다 튑니다.
   간격을 낱개의 오른쪽 여백으로 넣으면 낱개가 (w+p) 로 딱 떨어져 이음매가 없어집니다 */
/* will-change 는 걸지 않습니다 — 늘 도는 애니메이션이라 브라우저가 알아서 층으로
   올립니다. 명시하면 넓은 트랙이 통째로 한 층이 되어 오히려 무거워집니다 */
.mq-track{display:flex;flex:none;align-items:center;
  animation:mqroll 32s linear infinite}
.mq-track > span{flex:none;white-space:nowrap;text-transform:uppercase;
  -webkit-user-drag:none;padding-right:clamp(28px,3.4vw,66px);
  font-size:clamp(44px,5.2vw,100px);font-weight:700;letter-spacing:-.03em;line-height:1}
@keyframes mqroll{from{transform:translateX(0)}to{transform:translateX(-50%)}}
/* 손을 올리면 멈춥니다 — 읽고 싶을 때 멈출 수 있어야 합니다 */
.mq:hover .mq-track,.mq:focus-within .mq-track{animation-play-state:paused}
@media(prefers-reduced-motion:reduce){.mq-track{animation:none}}

/* ── 분석 파이프라인 ──────────────────────────────────────────────────
   2026-09-09 구조 교체. 스크롤을 가로채지 않습니다 —
   .pin 이 붙어 있는 동안 .pipespan 만큼 굴러가고, 그 위치가 단계가 됩니다.
   2026-09-09 에 옛 하이재킹 코드(284줄)를 지웠습니다 — 커밋 368d0b4 에 남아 있습니다. */
/* ★ 여기에 overflow:hidden 을 넣으면 안쪽 .pin 의 sticky 가 죽습니다.
   조상에 overflow 가 걸리면 그 상자가 스크롤 컨테이너가 되는데, 이 상자는 스크롤되지
   않아 붙을 자리가 없습니다. 이 저장소에서 세 번 당한 함정입니다. */
/* ★ 배경은 단색입니다. 2026-09-09 에 격자 + 상단 광원을 넣었다가 되돌렸습니다 —
   격자 자체가 별로였고, 고정된 판 뒤로 바닥이 흘러가는 것이 "스크롤이 조작되는" 느낌으로
   읽혔습니다(사용자). 굴리고 있다는 신호는 파티클 층이 맡습니다. 바닥은 가만히 있습니다. */
/* 시안의 옅은 바닥은 #F3F6FB, 우리 --bg 는 #F3F7FC 로 차이가 [0,+1,+1] 입니다.
   눈으로 구분이 안 되는데 한 페이지에 두 값이 섞일 이유가 없어 토큰으로 모읍니다
   (2026-09-11) */
.pipesec{position:relative;background:var(--bg)}
@media(max-width:900px){.pipesec{padding:100px 0}}

/* 제목·설명 — 고정 화면 **안** 오른쪽 열 머리에 둡니다.
   2026-09-09 에 한 번 고정 화면 밖 위로 뺐다가 되돌렸습니다 —
   구간에 들어오면 스크롤과 함께 사라져서 정작 읽히지 않았습니다(사용자). */
.pipehead{margin-bottom:26px}
.pipehead .d2{margin:0 0 10px;font-size:clamp(26px,2.4vw,36px)}
/* ~~15px · 44ch~~ -> 2026-09-10: 시안 Section/Title(28px)을 그대로 씁니다.
   44ch 로 묶으니 오히려 두 줄로 접혀 고정 구간의 세로를 더 먹었습니다 */
.pipehead .sec-sub{margin:0}
@media(max-width:900px){.pipehead{margin-bottom:18px}}

.pinwrap{position:relative;z-index:1}
/* 고정된 판이 붙어 있는 동안 굴러가는 거리.
     --pipe-step  한 단계를 넘기는 데 굴리는 거리. 단계는 넷이라 구간은 이 값의 3배
     --pipe-tail  마지막 단계(판정)를 띄운 뒤 머무는 거리.

   ★ 2026-09-10 — 꼬리를 46vh 에서 0 으로 내렸습니다 (사용자 판단).
     진행 레일이 생기면서 이 값이 **죽은 구간**이 됐습니다 —
     레일은 단계 구간(.pipespan)이 끝나는 지점에서 가득 차는데, 그 뒤로 46vh
     (900px 화면에서 414px, 휠 6~7번)를 더 굴려야 다음 섹션이 올라왔습니다.
     "다 됐다" 고 말해 놓고 아무 일도 안 일어나는 구간이라 불편합니다.
     이제 **레일이 가득 차면 그 다음 스크롤이 곧바로 겹침 시작**입니다.

     옛 주석은 "이게 없으면 판정이 뜨자마자 판이 떨어져 나갑니다" 였는데,
     지금은 히스테리시스(0.62) 덕에 판정이 단계 구간의 87 % 지점에서 이미 뜹니다.
     그 뒤로 레일이 차는 동안 267px + 겹치는 동안 900px 을 더 보여 줍니다. */
.pipesec{--pipe-step:78vh;--pipe-tail:0px}
.pipespan{height:calc(var(--pipe-step) * 3)}
.pipetail{height:var(--pipe-tail)}
/* ~~겹침 전환(sticky stack)~~ -> 2026-09-10 제거 (사용자: 시안과 안 어울립니다).
   다음 섹션이 고정된 판 위로 올라와 덮던 것이었습니다. 걷어낸 것:
     .pipecover{height:100vh} · .pipesec + .s{margin-top:-100vh}
     .pipesec ~ *{z-index:2;background:var(--bg)} · 덮을 때의 padding-top:220px
   지금은 구간이 끝나면 고정이 풀리고 다음 섹션이 평범하게 이어집니다.
   되살릴 일이 있으면 이 커밋 직전 이력에 있습니다. */
.pipecover{height:0}
@media(max-width:900px){
  .pipetail{height:0}
}
/* ★ 900px 이하는 .pipe 가 block 이 되고 캔버스가 .stagewrap 의 sticky 로 붙습니다.
   그 폭에서 구간 길이를 그대로 두면 빈 화면 셋을 굴리게 됩니다 —
   높이를 0 으로 만들면 pipeEdges 가 null 을 돌려주고 단계는 눌러서 옮깁니다.
   (JS 의 860 과 CSS 의 900 이 원래 어긋나 있어서 그 사이 폭이 비던 자리입니다) */
@media(max-width:900px){.pipespan{height:0}}
@media(max-width:900px){.pinwrap{position:static}.pipespan{display:none}}


.pin{position:sticky;top:0;height:100vh;display:flex;align-items:center;overflow:hidden}
/* 파티클 층 — 판(.stage) **안**에 둡니다.
   ★ 자리가 두 번 바뀐 항목입니다 (2026-09-09).
     ① 판 뒤(z-index:0) -> 어두운 카드가 통째로 덮어 아예 안 보였습니다
     ② 고정 화면 전체 위(z-index:3) -> 보이긴 하는데 판 밖으로 새어 나가고,
        판정 화면(.sum)까지 덮었습니다
     ③ 지금: 판 안. 카드가 overflow:hidden 이라 새어 나갈 수가 없고,
        .sum(z-index:2)이 자연히 위에 옵니다. JS 로 잘라내던 것도 필요 없어졌습니다 */
.stage .pipefx{position:absolute;inset:0;width:100%;height:100%;display:block;z-index:1;pointer-events:none}
.pin>.wrap{position:relative;z-index:1}
/* 좁은 화면에서는 고정이 없어 스크롤 반응이 성립하지 않습니다. 끕니다
   (선택자를 .stage .pipefx 와 맞춰야 합니다 — .pipefx 만 쓰면 특정도에서 집니다) */
@media(max-width:900px){.stage .pipefx{display:none}}
/* overflow:hidden 이 남아 있으면 안쪽 sticky 가 붙지 못합니다 —
   스크롤 컨테이너가 이 상자로 바뀌는데 이 상자는 스크롤되지 않습니다 */
/* ★ 문털을 900 으로 맞춥니다. 861~900 에서 .pipe 는 block 인데
   .pin 만 sticky · 100vh · overflow:hidden 이라 내용 1,213px 중 413px 가
   잘리고 도달할 수 없었습니다(2026-09-09 측정) */
@media(max-width:900px){.pin{position:static;height:auto;display:block;overflow:visible}}
/* ── 두 열의 비율과 정렬 (2026-09-09) ────────────────────────────────
   전에는 55:45(1.22:1) + align-items:center 였는데 재보니 셋이 어긋나 있었습니다 —
     ① 공유하는 모서리가 하나도 없었습니다 (판 y200~700 / 열 y117~783)
     ② 오른쪽 열 656px 중 글이 쓰는 건 393px. 263px(40%)가 의도 없이 비었습니다
     ③ 주인공인 판(500)이 오른쪽 내용(667)보다 낮았습니다
   그래서 7:5(12칼럼 표준 분할) + 판 4:3 으로 바꿉니다. 그러면 두 열의 높이가
   거의 같아져 **위·아래 모서리가 둘 다 맞습니다**(edge alignment).
   4:3 은 계측 장비·센서의 비율이라 계측기 뷰포트 방향과도 맞습니다.          */
/* ── 분석 과정 배치 — 디자이너 시안 (2026-09-10) ────────────────────────
   ~~좌: 판 / 우: 세로 목록~~ -> 위: 제목 · 판 / 아래: 카드 2x2
   ★ 고정 구간이라 이 전부가 100vh 안에 들어가야 합니다. 시안(1,103px)은 높이가
     넉넉한 화면에서의 모습이고, 짧은 화면에서는 판이 먼저 줄어듭니다(flex).
   ★ 진행 레일은 걷어냈습니다 — 카드 활성(파랑)이 같은 말을 합니다. 코드는 커밋 이력에 */
/* ★ 높이가 .pin(100vh) 부터 .pipe 까지 이어져야 판이 남는 자리를 채웁니다.
   .pin 은 align-items:center 라 안쪽 상자가 내용 높이로만 서 있었고,
   그래서 height:100% 가 기준을 못 찾아 판이 0 이 됐습니다.
   901px 이상에서만 겁니다 — 900 이하에서는 .pin 이 static/block 입니다 */
@media(min-width:901px){
  .pin{align-items:stretch}
  .pin > .wrap{height:100%}
}
.pipe{display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:clamp(18px,3vh,50px);width:100%;max-width:none;height:100%;margin:0;
  padding:calc(var(--nav-h) + 24px) 0 40px}
.pipe .pipehead{flex:none;margin-bottom:0}
/* 판 — 시안 1200x500 (2.4:1). 높이를 500 으로 묶으면 넓은 화면에서 시안보다 커지지
   않고(반응형 원칙 ③), 짧은 화면에서는 flex 가 줄여 카드 자리를 지킵니다 */
.pipe .stagewrap{flex:1 1 auto;min-height:0;max-height:500px;width:100%;
  display:flex;justify-content:center;align-self:auto}
/* ★ 기본 .stage 의 min-height:min(600px,70vh) · max-height:80vh 를 풀어야 합니다.
   그 값들은 두 열 배치에서 오른쪽 열과 아래 모서리를 맞추려던 것이고,
   여기서는 판을 600 으로 밀어 카드 자리를 먹습니다 */
.pipe .stage{height:100%;width:auto;aspect-ratio:2.4/1;max-width:100%;
  min-height:0;max-height:none}
/* 판을 감싸 레일의 기준을 만듭니다 — 판은 폭이 높이에 따라 변하므로
   레일을 .stagewrap 에 붙이면 판에서 떨어져 버립니다 */
.stagebox{position:relative;height:100%;display:flex}
/* 진행 레일 — 판 왼쪽 세로. 채우기는 CSS 가 하고 값(--rail)은 landing.js 가 넘깁니다 */
.prail{position:absolute;left:-26px;top:0;width:2px;height:100%;border-radius:1px;
  background:var(--ghost);pointer-events:none}
.prail i{position:absolute;inset:0;border-radius:1px;background:var(--brand);
  transform-origin:top center;transform:scaleY(var(--rail,.25))}
@media(max-width:900px){.prail{display:none}}
.pipeinfo .pipehead{margin-bottom:0}
/* ── 짧은 화면 (2026-09-09 측정) ──────────────────────────────────────
   .pin 은 100vh 이고 overflow:hidden 입니다. 오른쪽 열은 뷰포트 높이와
   무관하게 553px 라, 창이 낮으면 아래가 잘리고 **도달할 수 없습니다**.
     잰 값(1440 폭)  vh 560 여유 3px · vh 540 부터 잘림 ·
                    vh 500 에서 4단계(판정) 24px + 점 27px 가 잘림
   해당 범위는 폭 901px 이상 × 높이 545px 미만입니다. 폭 900 이하는 고정이
   풀려 해당 없고, 확대 400 % 는 폭이 900 아래로 내려가 역시 해당 없습니다.
   -> 잘라서 감추느니 줄여서 보여줍니다. 부제를 접고 나머지를 조입니다.      */
@media(min-width:901px) and (max-height:620px){
  .pipehead .sec-sub{display:none}
  .pipe .st{padding:7px 0}
  .pipe .st .no{font-size:clamp(26px,2.2vw,32px)}
  .pipe .pipehead .d2{font-size:clamp(22px,2vw,28px)}
}
@media(max-width:900px){
  /* 그리드 셀 안에서는 sticky 가 움직일 여지가 없습니다(셀 높이 = 요소 높이).
     좁은 화면에서는 블록으로 바꿔 캔버스가 구간 전체에서 붙어 있게 합니다 */
  /* ★ 세로 순서: 제목·설명 -> 판 -> 단계목록 -> 점.
     예전에는 판이 먼저 나와서, 이 섹션이 무엇을 말하는지 모른 채 그림부터 봤습니다.
     .pipeinfo 는 display:contents 로 상자를 없애 자식들이 .pipe 의 항목이 되게 합니다 */
  .pipe{display:flex;flex-direction:column}
  .pipeinfo{display:contents}
  .pipe .pipehead{order:0}
  .pipe .stagewrap{order:1;align-self:stretch}
  /* 캔버스를 화면에 붙여 둡니다. 단계를 눌러 놓고 아래로 내려가도
     무엇이 바뀌었는지 같이 보여야 합니다 — 데스크톱의 고정 구간이 하는 일입니다 */
  /* .pipe 를 앞에 붙여 뒤에 오는 기본 .stagewrap 규칙을 이깁니다 */
  /* ★ 배경이 본문 열 폭(331px)만 덮어서 좌우 여백 22px 로 뒤 글자가 비쳤습니다
     (2026-09-09 측정 — 걸린 지점이 전부 x=4). 그림자를 좌우로 길게 깔아 화면 끝까지
     같은 색으로 메웁니다. 그림자는 스크롤 영역을 늘리지 않아 가로 넘침이 안 생깁니다 */
  /* ★ 캔버스는 본문 열 폭(331px)뿐이라 **좌우 여백(각 22px)이 투명**합니다.
     그 틈으로 뒤에서 올라오는 단계 이름이 비쳤습니다.
     spread 로 사방을 덮은 뒤 clip-path 로 위아래를 잘라 좌우로만 화면 끝까지 메웁니다.
     ★ 처음에 box-shadow 를 -100vw **오프셋**으로 줬는데, 그러면 그림자가 통째로
       화면 밖으로 나가 아무것도 안 덮습니다. 덮으려면 오프셋이 아니라 spread 입니다. */
  /* 캔버스를 화면 꼭대기에서 조금 내려 세웁니다.
     ★ top 을 내리면 안 됩니다 — 내비와 판 사이에 덮이지 않는 띠가 생겨 그리로 글자가
       지나갑니다(2026-09-09 에 실제로 그랬습니다). 붙는 자리는 내비에 그대로 두고
       **안쪽 여백**으로 캔버스만 내립니다. 그러면 불투명한 판이 내비까지 이어집니다.
     ★ 이 값이 바뀌면 단계가 넘어가는 기준선(판의 아래 모서리)도 같이 내려갑니다 —
       pipeStepMobile 은 판의 실제 위치를 읽으므로 따로 맞출 것이 없습니다 */
  .pipe .stagewrap{position:sticky;top:var(--nav-h,62px);
    --swdrop:clamp(28px,8vh,72px);
    z-index:2;padding:calc(10px + var(--swdrop)) 0 10px;
    --swbg:color-mix(in srgb,var(--fg) 3.5%, var(--bg));
    background:var(--swbg);
    box-shadow:0 0 0 100vw var(--swbg);
    clip-path:inset(0 -100vw)}
  /* ★ 세로 간격 — .pipe 의 gap:64px 는 **가로 두 열 사이** 값입니다.
     모바일에서 세로로 쌓이면 그 64px 이 제목 아래·판 아래에 그대로 들어가
     1단계 글자까지 90px 이 비었습니다(2026-09-10 사용자 지적). 20px 로 줄입니다. */
  /* ★ padding-top 도 같이 없앱니다 — calc(var(--nav-h)+24px) 는 **데스크톱에서 판이
     고정됐을 때 제목을 내비 아래로 내리는 값**입니다. 열 레이아웃에서는 .pin 이 static 이고
     고정되는 것은 .pipe .stagewrap 이라 그쪽이 자기 top 으로 내비를 피합니다.
     여기 남겨두면 제목만 88px 밀려 다른 섹션과 어긋납니다 (2026-09-14) */
  .pipe{gap:20px;padding-top:0}
  /* ★ 판은 모바일에서 폭이 정하고 세로로 눕습니다 — 데스크톱의 height:100% 는
     sticky 래퍼 안에서 기준을 못 찾아 111px 로 쪼그라들었습니다(09-10 측정).
     비율은 4:3 을 유지합니다 — 시안에 모바일이 없고, 좁은 열에서 2.4:1 은
     138px 밖에 안 나와 개체가 안 보입니다(반응형 원칙 ③ 모바일 현행 유지) */
  .pipe .stagewrap{max-height:none}
  .pipe .stagebox{display:block;height:auto;width:100%}
  .pipe .stage{height:auto;width:100%;aspect-ratio:4/3;max-height:none}
  /* 카드는 한 줄에 하나씩 — 2열이면 폭이 138px 라 설명이 다섯 줄로 접힙니다.
     항목 사이 간격이 곧 그 단계가 유지되는 스크롤 거리입니다 */
  /* ★ 이 간격이 곧 "단계 하나가 유지되는 스크롤 거리" 입니다 (2026-09-14).
     pipeStepMobile 은 이전 카드의 중점이 판 아래 모서리를 지나면 다음 단계로 넘깁니다 —
     즉 전환 사이의 거리 = 카드 사이의 거리입니다. 20px 이면 145px 마다 넘어가서
     너무 빨랐습니다(사용자 지적). 늘리면 카드마다 자기 차례가 생깁니다 */
  .pipe .steps2{order:2;grid-template-columns:1fr;gap:56px}
  .pipe .st{padding:20px 18px;min-height:0;gap:6px}
  .pipe .st h3{margin-top:6px}
  .pipe .st .ic{width:52px;right:16px}
}
/* ── 아주 낮은 화면 — 붙이지 않습니다 (2026-09-09 측정) ────────────────
   붙는 판은 내비(62) + 여백 + 판 높이(폭의 3/4)를 먹습니다. 화면이 그보다
   낮으면 판이 화면을 통째로 덮어 **단계 목록이 영영 안 보입니다.**
     잰 값(320×256 = 확대 400 % 기준 뷰포트)
       판 62..354 · 화면 256 까지 -> 목록이 한 줄도 안 보임 (WCAG 1.4.10 손실)
   가로로 든 폰(844×390 등)도 같은 범위에 들어옵니다.
   -> 이 범위에서는 고정을 풀어 판이 위로 흘러가게 둡니다. 단계는 스크롤
      위치로 정하므로(pipeStepMobile 이 판의 실제 위치를 읽습니다) 그대로 돕니다. */
@media(max-width:900px) and (max-height:520px){
  .pipe .stagewrap{position:static;padding:10px 0;
    box-shadow:none;clip-path:none;background:transparent}
  .stage{max-height:62vh}
}
/* 칩이 캔버스 밖으로 나올 자리. .stage 는 overflow:hidden 이라
   그 안에 두면 좁은 화면에서 캔버스 위에 겹쳐 앉습니다 */
.stagewrap{position:relative;min-width:0}
/* ★ min-height 가 아래 모서리를 지킵니다.
   오른쪽 열의 자연 높이는 폭이 변해도 554~601 로 거의 일정한데, 판은 4:3 이라
   폭을 따라 줄어듭니다(1000px 에서 375). 그러면 1500px 아래에서 아래 모서리가
   최대 179px 까지 벌어집니다. 하한을 두면 그 구간에서도 ±30px 안에 들어옵니다.
   짧은 뷰포트에서는 62vh 가 먼저 걸려 판이 화면을 넘지 않습니다. */
.stage{position:relative;border-radius:4px;overflow:hidden;aspect-ratio:4/3;
  width:100%;min-height:min(600px,70vh);max-height:80vh;
  box-shadow:0 34px 100px -36px rgba(0,0,0,.55)}
/* 하한은 데스크톱에서 두 열의 아래 모서리를 맞추려던 값입니다. 모바일에는 맞출 상대가
   없고, 판이 70vh 를 먹으면 단계 목록이 166px 밖에 안 보여 스크롤로 넘길 자리가
   없습니다. 비율(4:3)만 따르게 둡니다.
   ★ 기본 .stage 규칙 뒤에 두어야 합니다 — 특정도가 같아 앞에 두면 집니다 */
@media(max-width:900px){.stage{min-height:0}}

/* ── 판 생김새 시안 (2026-09-09) ──────────────────────────────────────
   지금의 "둥근 네모 카드" 는 시야도 계측 화면도 아닌 일반 상자라 어느 쪽으로도
   안 읽힙니다. 두 방향을 만들어 두고 고릅니다. 고른 뒤 진 쪽은 지웁니다.
   ★ 캔버스 그리기(landing.js)는 건드리지 않습니다 — 테두리만 다릅니다.       */

/* B · 계측기 뷰포트 — "이건 장비의 출력 화면이다"
   각진 모서리 + 얇은 테두리 + 모서리 브래킷 + 위아래 눈금.
   ★ 스케일 바는 넣지 않았습니다 — 배율을 모르면 µm 눈금은 지어내는 것이 됩니다 */
.stage{box-shadow:0 22px 60px -30px rgba(0,0,0,.5);
  outline:1px solid color-mix(in srgb,#9fc4e8 22%, transparent);outline-offset:0}
/* 모서리 브래킷 넷 — 배경 그라디언트 여덟 장으로 그립니다(마크업 추가 없이) */
.stage::before{content:"";position:absolute;inset:11px;pointer-events:none;z-index:2;
  --l:color-mix(in srgb,#bcd8f2 46%, transparent);
  background:
    linear-gradient(var(--l),var(--l)) 0 0/20px 1px no-repeat,
    linear-gradient(var(--l),var(--l)) 0 0/1px 20px no-repeat,
    linear-gradient(var(--l),var(--l)) 100% 0/20px 1px no-repeat,
    linear-gradient(var(--l),var(--l)) 100% 0/1px 20px no-repeat,
    linear-gradient(var(--l),var(--l)) 0 100%/20px 1px no-repeat,
    linear-gradient(var(--l),var(--l)) 0 100%/1px 20px no-repeat,
    linear-gradient(var(--l),var(--l)) 100% 100%/20px 1px no-repeat,
    linear-gradient(var(--l),var(--l)) 100% 100%/1px 20px no-repeat}
/* 위·아래 가장자리 눈금 */
.stage::after{content:"";position:absolute;left:42px;right:42px;top:11px;bottom:11px;
  pointer-events:none;z-index:2;opacity:.34;
  --l:color-mix(in srgb,#bcd8f2 60%, transparent);
  background:
    repeating-linear-gradient(90deg,var(--l) 0 1px,transparent 1px 26px) 0 0/100% 5px no-repeat,
    repeating-linear-gradient(90deg,var(--l) 0 1px,transparent 1px 26px) 0 100%/100% 5px no-repeat}
.stage canvas{position:absolute;inset:0;width:100%;height:100%;display:block}
.tip{position:absolute;pointer-events:none;opacity:0;transform:translate(-50%,-118%);
  background:rgba(9,14,24,.94);border:1px solid rgba(255,255,255,.16);border-radius:9px;
  padding:9px 12px;font-size:12px;line-height:1.6;color:#fff;white-space:nowrap;
  transition:opacity .18s ease;z-index:3}
.tip.on{opacity:1}
.tip b{font-weight:800}
.tip .g{display:inline-block;width:7px;height:7px;border-radius:2px;margin-right:6px}
.sum{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:center;
  padding:0 9%;pointer-events:none;z-index:2}
.sum .big{font-size:clamp(44px,5.6vw,76px);font-weight:800;letter-spacing:-.05em;
  color:#fff;line-height:1;margin-bottom:12px}
.sum .cap2{font-size:17px;color:rgba(255,255,255,.72);margin-bottom:30px}
.sum .row{display:flex;gap:34px;flex-wrap:wrap;font-size:16px;color:rgba(255,255,255,.72)}
.sum .row b{color:#fff;font-weight:800}
/* 판정 화면은 데스크톱 기준(최소 44px)이라 좁은 화면에서 캔버스 밖으로 넘칩니다 */
@media(max-width:640px){
  .sum{padding:0 7%}
  .sum .big{font-size:clamp(30px,9.5vw,44px);margin-bottom:7px}
  .sum .cap2{font-size:12.5px;margin-bottom:16px}
  .sum .row{gap:6px 16px;font-size:12.5px}
}
.steps2{display:grid;gap:4px}

/* 단계 목록 — 번호를 큰 조형 요소로 올립니다(2026-09-09).
   ★ 예전 규칙은 `.st h4` 였는데 스크립트는 <h3> 를 내보내고 있었습니다.
     제목을 h4->h3 으로 바꿀 때 선택자를 안 따라가서 제목이 브라우저 기본값(18.1px)으로
     나오고 있었습니다 — 잰 값으로 확인하고 여기서 고쳤습니다 */
/* 카드 2x2 — 시안 580x200, 가로 간격 40 · 세로 간격 30.
   1200 컨테이너에서 (1200-40)/2 = 580 이라 폭이 저절로 맞습니다 */
.steps2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:30px 40px;
  width:100%;flex:none}
.st{position:relative;isolation:isolate;overflow:hidden;text-align:left;width:100%;
  display:flex;flex-direction:column;justify-content:center;
  gap:clamp(12px,2.4vh,27px);
  min-height:clamp(112px,15.5vh,200px);
  padding:clamp(18px,3.4vh,40px) 120px clamp(18px,3.4vh,40px) 40px;
  border-radius:20px;background:#fff;
  /* 옅은 바닥(#F3F6FB) 위에 흰 카드라 경계가 약합니다 — 시안처럼 살짝 띄웁니다 */
  box-shadow:0 4px 20px rgba(28,42,57,.09);
  transition:background-color .45s ease,box-shadow .45s ease,color .45s ease}
.st .no{font-size:18px;font-weight:700;line-height:1.2;letter-spacing:-.03em;
  color:var(--brand);transition:color .45s ease}
.st h3{font-size:clamp(20px,2.6vh,28px);font-weight:700;letter-spacing:-.03em;
  line-height:1.2;color:var(--t-title);margin-top:12px;
  transition:color .45s ease}
/* ★ 활성 카드 — 시안은 파란 그라디언트 위에 검정 20 % 를 덮습니다.
   ★ 그라디언트(background-image)는 transition 이 안 먹습니다 — 글자색만 부드럽게
     바뀌고 카드 색은 툭 바뀌었습니다(09-10 사용자 지적). 버튼에서 쓴 것과 같은 방법으로,
     가상 요소에 깔고 opacity 를 전환합니다. z-index:-1 + isolation 으로 글자 아래에 둡니다 */
.pipe .st::before{content:"";position:absolute;inset:0;border-radius:inherit;z-index:-1;
  opacity:0;transition:opacity .45s ease;
  background-image:linear-gradient(rgba(0,0,0,.2),rgba(0,0,0,.2)),
    linear-gradient(79deg,var(--brand) 2%,#0055EB 101%)}
.pipe .st.on::before{opacity:1}
.pipe .st.on{color:#fff;box-shadow:0 4px 20px rgba(28,42,57,.2)}
.pipe .st.on .no,.pipe .st.on h3{color:#fff}
/* ★ shell.css 에도 `.st` 규칙이 있고(background:transparent · hover 시 opacity .72)
   그 파일이 뒤에 붙어 같은 특정도에서 이깁니다 — 카드가 투명해져 바닥과 같아 보였습니다
   (09-10 사용자 지적). `.pipe` 를 붙여 특정도로 넘습니다.
   ★ 새 클래스는 grep '.이름' site/assets/css/*.css 로 먼저 확인 — CLAUDE.md */
/* ★ background 는 단축 속성입니다 — 여기서 shorthand 를 쓰면 아래 .st.on 의
   background-image(그라디언트)까지 지워집니다. 실제로 활성 카드가 흰 바닥 +
   흰 글자가 되어 글자가 사라졌습니다(09-10). 색만 바꿉니다 */
.pipe .st{background-color:#fff}
.pipe .st:hover{opacity:1;box-shadow:0 8px 26px rgba(28,42,57,.16)}
.pipe .st.on:hover{box-shadow:0 4px 20px rgba(28,42,57,.24)}
/* 아이콘 — 카드 오른쪽. 활성일 때만 또렷하게 */
.st .ic{position:absolute;right:26px;top:50%;transform:translateY(-50%);
  width:clamp(58px,8vh,104px);height:auto;opacity:.55;
  transition:opacity .45s ease}
.st.on .ic{opacity:1}
/* 설명은 선 단계에서만 폅니다. 넷을 다 펴 두면 화면이 글자로 가득 찹니다.
   ★ max-height 로 접지 않습니다 (2026-09-09 에 바꿨습니다).
     내용이 1줄(24px)인데 max-height 를 96px 로 두면 —
       펼침 0->96 은 전체의 25% 만에 이미 다 보이고
       접힘 96->0 은 75% 가 지나서야 줄어들기 시작합니다
     그래서 동시에 시작해도 앞의 75% 동안 둘 다 펼쳐져 **높이가 늘었다 줄었습니다**.
     0fr -> 1fr 은 실제 높이에 선형이라 접힘과 펼침이 정확히 상쇄됩니다. */
/* 시안은 카드 넷이 늘 설명을 보여줍니다 */
.st p{font-size:clamp(14px,2vh,18px);line-height:1.5;letter-spacing:-.03em;
  color:#6B6B6B;transition:color .45s ease}
.st.on p{color:rgba(255,255,255,.92)}
/* ★ 화면이 낮으면 판이 먼저 쪼그라듭니다 — 시안 스택(1,103)이 1080p 브라우저
   뷰포트(약 990)에도 원래 안 들어갑니다. 그 구간에서는 설명을 활성 카드에서만 펴서
   판에 자리를 돌려줍니다. 0fr -> 1fr 은 실제 높이에 선형이라 접힘·펼침이 상쇄됩니다
   (max-height 로 접으면 어긋납니다) */
@media(min-width:901px) and (max-height:1150px){
  /* 카드를 한 줄로 — 두 줄이 차지하던 높이(약 200px)를 판에 돌려줍니다 */
  .steps2{grid-template-columns:repeat(4,minmax(0,1fr));gap:0 20px}
  /* ★ 아이콘은 남깁니다 — 카드에서 아이콘을 빼면 시안과 인상이 크게 달라집니다
     (09-10 사용자 지적). 대신 작게 넣고 글 자리를 그만큼 비웁니다.
     판은 그만큼 줄지만, 부제를 한 줄로 되돌려 얻은 자리로 상쇄됩니다 */
  .st{padding:16px 76px 16px 20px;gap:6px;min-height:0}
  .st h3{margin-top:6px;font-size:20px}
  .st .ic{width:clamp(38px,5.4vh,52px);right:18px}
  /* ★ 설명을 접지 않습니다. 활성 카드만 펴면 그 카드가 높아지고 -> 줄 높이가 변하고
     -> 판에 남는 자리가 매 단계 달라져 판이 출렁입니다(09-10 사용자 지적).
     넷 다 펴 두면 높이가 고정되고 판도 가만히 있습니다 */
  .st p{font-size:14px;line-height:1.45}
}
@media(prefers-reduced-motion:reduce){.st,.st .no,.st h3,.st p,.st .ic{transition:none}}
@media(prefers-reduced-motion:reduce){
  .st .no,.st h3,.st p{transition:none}}

/* 타입 */
.d1{font-size:clamp(29px,3.4vw,44px);font-weight:800;letter-spacing:-.038em;line-height:1.32}
.d2{font-size:clamp(24px,2.6vw,34px);font-weight:800;letter-spacing:-.034em;line-height:1.38}
.lead{font-size:16px;line-height:1.85;color:var(--muted);max-width:42ch;margin-top:22px}
.body{font-size:15px;line-height:1.8;color:var(--muted);max-width:44ch}
.mono{font-variant-numeric:tabular-nums}
.center{text-align:center}
.center .lead,.center .body{margin-left:auto;margin-right:auto}
/* ── 버튼 — 시안 Button / Hero-button 컴포넌트 (2026-09-10) ──────────────
   밝은 배경   기본: 옅은 파란 테두리 + 파란 글씨 / hover: 남색 그라디언트 채움 + 흰 글씨
   어두운 배경  .btn.on-dark — 기본: 보라 테두리 + 흰 글씨 / hover: 보라 그라디언트 채움
   테두리 색은 시안 렌더에서 잰 #BACCEB 을 brand 기준으로 다시 쓴 값입니다 */
.btn{position:relative;isolation:isolate;overflow:hidden;
  display:inline-flex;align-items:center;justify-content:center;
  width:270px;height:70px;border-radius:500px;cursor:pointer;text-decoration:none;
  background:transparent;color:var(--brand);border:0;
  /* ★ 테두리를 border 로 그리지 않습니다 — 1px 테두리는 알약 끝의 곡선에서
     길게 늘어나 보이고, 채움(::before)과 다른 층이라 끝에서 초승달처럼 어긋납니다
     (09-10 사용자 확대 캡처로 확인). inset 그림자는 배경 위에 그려지고
     채움이 그 위를 덮으므로 끝이 깨끗합니다 */
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--brand) 27%, #fff);
  font:inherit;font-size:22px;font-weight:700;letter-spacing:-.02em}
.btn.on-dark{color:#fff;font-size:24px;box-shadow:inset 0 0 0 1px var(--violet)}
/* ★ 채움은 가상 요소로 합니다 — background-image(그라디언트)는 transition 이
   안 먹어서 즉시 나타납니다. 그동안 테두리만 0.2초에 걸쳐 사라져,
   곡선 끝에 1px 테두리가 남아 "끝이 잘린" 것처럼 보였습니다(09-10 사용자 지적).
   overflow:hidden 이 알약 모양으로 자릅니다 */
.btn::before{content:"";position:absolute;inset:0;border-radius:inherit;z-index:-1;
  opacity:0;transition:opacity .28s ease;
  background-image:linear-gradient(105deg,var(--brand) 1%,#011E51 112%)}
.btn.on-dark::before{background-image:linear-gradient(96deg,var(--violet) 13%,#fff 188%)}
.btn:hover::before{opacity:1}
.link{display:inline-block;color:var(--accent);font-size:14.5px;font-weight:700;
  text-decoration:none;border:0;background:0;font-family:inherit;cursor:pointer;padding:0}
.link:hover{text-decoration:underline}
.btns{margin-top:36px}

/* 히어로 */
/* 시안 히어로 — 전부 가운데 정렬. 요소 사이 간격은 시안에서 잰 값입니다
   (제목 아래 79 · 지표 아래 40 · 글 아래 40)
   ★ 높이는 픽셀이 아니라 "한 화면" 입니다.
     시안의 950 을 그대로 박았더니 2560 화면에서 71 % 만 차지했고,
     맨 아래 Scroll 표시가 화면 한가운데 떠서 뜻을 잃었습니다 */
/* ★ 히어로는 y=0 에서 시작해 고정 nav 아래로 들어갑니다. 그래서 높이에서 nav 를
   빼면 안 되고(그러면 화면보다 80 짧아집니다), 위 여백으로 비켜야 합니다.
   위=nav+96 · 아래=96 으로 두면 내용의 중심이 nav 아래 영역의 정중앙에 옵니다 */
.hero-in{position:relative;display:flex;flex-direction:column;align-items:center;
  justify-content:center;text-align:center;
  padding:calc(var(--nav-h) + 96px) 0 96px;
  /* ★ 2026-09-15 — `+1px` 입니다 (사용자 지적: 1080p 에서 화면 맨 아래 흰 줄).
     100vh 로 딱 맞추면 **히어로 아래끝과 다음 섹션의 위끝이 같은 기기화소를 나눠 씁니다.**
     윈도우 배율 125 %(DPR 1.25)를 모사해 재현했습니다 —
       innerHeight 863 CSS x 1.25 = 1,078.75 기기화소 -> 소수부 0.75
       그 화소 한 줄이 `히어로 75 % + 흰 섹션 25 %` 로 섞여 옅은 줄로 보입니다
     1px 을 더 그리면 경계가 화면 밖으로 나가 섞일 것이 없어집니다.
     ★ 배율·창 높이·모니터가 바뀌면 소수부가 0이 되어 **안 보이기도 합니다** —
       "어제는 보였는데 오늘은 안 보인다" 가 정상입니다. 원인은 그대로 있습니다
     ★ 히어로 높이에 기대는 JS 는 없습니다(확인함) */
  min-height:calc(100vh + 1px);
  min-height:calc(100svh + 1px)}   /* svh — 모바일 주소창이 접혀도 안 튑니다 */
.hero-h1{margin:0;font-size:60px;font-weight:700;letter-spacing:-.02em;line-height:1.3;
  color:#fff}
/* 지표 캡슐 — 반투명 흰 판 위에 셋. 사이에 세로 선 */
/* ★ 여기도 backdrop-filter 를 뺐습니다 — 같은 이유(등장 중 변형)로 끝에서 튑니다.
   2px 흐림이라 눈에 띄는 차이도 없었습니다 */
.hero-stats{display:flex;align-items:center;justify-content:center;gap:100px;
  margin-top:79px;width:1000px;max-width:100%;padding:31px 10px;border-radius:24px;
  background:rgba(255,255,255,.1)}
.hero-stats > div{display:flex;flex-direction:column;align-items:center;gap:12px}
.hero-stats b{font-size:30px;font-weight:700;letter-spacing:-.02em;line-height:1.3}
.hero-stats span{font-size:18px;font-weight:400;letter-spacing:-.02em;line-height:1.3;
  color:rgba(255,255,255,.82)}
.hero-stats i{flex:none;width:1px;height:80px;background:rgba(255,255,255,.25)}
.hero-lead{margin:40px auto 0;font-size:24px;line-height:1.58;color:rgba(255,255,255,.82);
  max-width:640px}   /* 시안의 두 줄 폭(614)에 맞춥니다 — 넓은 화면에서 한 줄로 퍼지지 않게 */
.hero-in .btns{margin-top:40px}
/* 아래로 내려가라는 표시 — 시안 히어로 맨 아래 */
/* ★ 화면 아래에 붙입니다 — 내용 흐름에 두면 화면이 커질수록 가운데로 떠오르고
   "아래에 더 있다" 는 뜻이 사라집니다 */
.scrolltip{position:absolute;left:50%;bottom:40px;transform:translateX(-50%);
  display:inline-flex;flex-direction:column;align-items:center;gap:6px;
  color:rgba(255,255,255,.7);text-decoration:none;font-size:11px;
  letter-spacing:.06em;transition:color .2s}
.scrolltip:hover{color:#fff}
.scrolltip svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.6;
  stroke-linecap:round;stroke-linejoin:round}
@media(max-width:900px){
  .hero-in{padding:calc(var(--nav-h) + 56px) 0 56px}
  .hero-h1{font-size:clamp(30px,6.4vw,60px)}
  .hero-stats{gap:0;justify-content:space-between;padding:22px 18px;margin-top:44px}
  .hero-stats b{font-size:22px}
  .hero-stats span{font-size:13px}
  .hero-stats i{height:56px}
  .hero-lead{font-size:16px;margin-top:28px}
  .hero-in .btns{margin-top:28px}
  .scrolltip{bottom:28px}
}
.stats{display:grid;grid-template-columns:repeat(3,1fr);gap:30px;max-width:760px;
  border-top:1px solid var(--line);padding:30px 0 0}
.stats b{display:block;font-size:25px;font-weight:800;letter-spacing:-.035em;
  line-height:1;margin-bottom:8px}
.stats b small{font-size:.52em;font-weight:700}
.stats > div > span{font-size:13px;color:var(--muted)}   /* 라벨만. 숫자 안의 span 은 제외 */
@media(max-width:640px){
  .stats{grid-template-columns:repeat(3,1fr);gap:14px;padding-top:24px}
  .stats b{font-size:21px;margin-bottom:6px}
  .stats > div > span{font-size:11.5px;line-height:1.5}}

/* 섹션 */
.s{padding:190px 0}
.s.tight{padding:140px 0}
.s.soft{background:color-mix(in srgb,var(--fg) 3.5%, var(--bg))}
/* 흰 바닥. 옅은 바닥·짙은 바닥과 번갈아 놓아 섹션을 가릅니다 */
.s.paper{background:var(--surface)}
/* 어두운 섹션 — 시안 값 그대로(사용자 결정 A) */
.s.dark{background:var(--d-flow);color:#fff}
/* 검사 흐름 배경 — 시안 그래픽(세로 빛기둥). 코드로 못 만드는 그림이라 원본을 씁니다.
   ★ cover + center 로 두면 폭이 변할 때 가운데를 기준으로 잘립니다.
     세로로는 위쪽(기둥)이 남고 아래 반사 바닥이 먼저 잘리도록 30 % 지점을 잡았습니다 */
/* ★ 시안은 그림을 그대로 쓰지 않고 어둡게 덮습니다 — 재보니 검정 50 % 입니다
   (평균 밝기 35.4 -> 17.8, 상위 10 % 93.7 -> 44.0).
   덮지 않으면 배경이 글자를 이기고 유리판도 안 읽힙니다.
   그라디언트 한 겹을 이미지 위에 깔아 처리합니다(요소를 더 만들지 않습니다) */
/* ★ 2026-09-15 — 그림을 `.bgnear` 로 내렸습니다. 이 섹션은 문서 5,308px 지점인데
   (뷰포트 900) 그림 167KB 가 **로드 226ms 에** 히어로 영상과 같이 왔습니다.
   근접하면 landing.js 가 .bgnear 를 답니다. 색은 기본값에 남아 있어 빈 칸이 안 보이고,
   덮개(검정 50 %)는 그림과 한 쌍이라 같이 내렸습니다.
   JS 가 아예 안 도는 경우는 index.html 의 <noscript> 가 받습니다 */
#flow{background-color:var(--d-flow)}
#flow.bgnear{
  background-image:linear-gradient(rgba(0,0,0,.5),rgba(0,0,0,.5)),
    url("../img/flow-bg.webp");
  background-size:cover,cover;background-position:center,center 30%;
  background-repeat:no-repeat,no-repeat}
.s.dark .d2{color:#fff}
.s.dark .sec-sub{color:rgba(255,255,255,.78)}
/* 비교 섹션 — 시안 값.
   ★ 배경 물결은 비워 뒀습니다. 내보낸 렌더를 깔았더니 화질이 깨져서
     (1920 기준 그림을 2560 까지 늘리는 구조) 히어로처럼 캔버스로 다시 그리기로 했습니다
     (2026-09-10 사용자 결정). 원본 렌더는 docs/references/cmp-wave.webp */
/* ★ 배경 물결 (2026-09-11). 원본 여백이 정확히 #FFFFFF 라 두 섹션 다 흰 바닥입니다 —
     #result 는 규칙이 아예 없어 --bg(#F3F7FC)를 상속하고 있었습니다.
     ★ #result 의 캔버스는 아직 없습니다 — 같은 엔진으로 별도 곡선을 그릴 예정입니다.
       자리(position·overflow·z-index)는 미리 잡아 둡니다.
     캔버스는 흐름에서 빠지므로 .wrap 을 z-index 로 올려 글자를 위에 둡니다. */
#intro,#result{position:relative;background:#fff;overflow:hidden}
.wavebg{position:absolute;inset:0;width:100%;height:100%;display:block;
  z-index:0;pointer-events:none}
/* ★ 모바일에서는 안 그립니다 (2026-09-11 사용자 결정). 그림이 2.09:1 인데 섹션이
   세로로 길어 어떻게 맞춰도 어중간합니다 — 조각이 되거나 띠로 뜹니다.
   760 은 새로 만든 값이 아니라 바로 아래 .s 여백 규칙과 같은 자리입니다 */
@media(max-width:760px){.wavebg{display:none}}
#intro > .wrap,#result > .wrap{position:relative;z-index:1}
#intro{padding:150px 0 106px}
@media(max-width:760px){.s{padding:100px 0}.s.tight{padding:80px 0}}

/* ── 모바일 섹션 제목 위 여백 맞추기 (2026-09-14) ─────────────────────────
   390 에서 재보니 제목까지의 거리가 제각각이었습니다 —
     비교 170 · 분석 과정 188 · 검사 흐름/결과/정확도 100
   뒤 셋(.s.tight)에 맞춰 100 으로 모읍니다. 원인이 둘로 달랐습니다.

   ① #intro 는 **ID 선택자라 바로 위 .s 미디어쿼리를 이깁니다.**
      순서가 아니라 특정도로 진 경우이고, 그래서 모바일에서도 데스크톱 값 150 이
      그대로 남아 있었습니다
   ② .pipe 의 padding-top 은 calc(var(--nav-h) + 24px) = 88px 인데,
      이건 **데스크톱에서 판이 고정됐을 때 제목을 내비 아래로 내리는 값**입니다.
      모바일에서는 .pin 이 static 이고(확인함) 고정되는 것은 .pipe .stagewrap 이라
      그쪽이 자기 top 으로 내비를 피합니다 — 이 88 은 하는 일 없이 제목만 밀고 있었습니다.
      같은 파일 위쪽 gap:64px 이 샜던 것과 같은 종류입니다 */
@media(max-width:760px){
  #intro{padding:80px 0}         /* .s.tight 와 같은 값 -> 제목까지 100 */
  .pipesec{padding-top:100px}    /* 100 + .pipe 0 = 100 */
}
/* 태블릿 구간도 같은 원리로 맞춥니다 — 여기서는 .s.tight 가 140 이라 제목까지 160 입니다 */
@media(min-width:761px) and (max-width:900px){
  #intro{padding:140px 0}        /* -> 제목까지 160 */
  .pipesec{padding-top:160px}    /* 160 + .pipe 0 = 160 */
}
.two{display:grid;grid-template-columns:1fr 1fr;gap:64px;align-items:center}
@media(max-width:860px){.two{grid-template-columns:1fr;gap:40px}}
.nouns{font-size:19px;font-weight:700;letter-spacing:-.022em;line-height:1.66;margin-top:22px}

/* 시간 비교 */
.time{margin-top:60px;max-width:600px}
.trow{display:grid;grid-template-columns:100px 1fr;gap:20px;align-items:center;padding:14px 0}
@media(max-width:600px){.trow{grid-template-columns:1fr;gap:6px}}
.trow .who{font-size:14px;color:var(--muted)}
.trow .who.us{color:var(--fg);font-weight:700}
.tbar{display:flex;align-items:center;gap:14px}
.tbar i{display:block;height:10px;border-radius:100px;background:var(--ghost);
  transform-origin:left;transform:scaleX(0);transition:transform 1.1s cubic-bezier(.22,.61,.36,1) .15s}
.in .tbar i,.tbar.on i{transform:scaleX(1)}
.tbar.us i{background:var(--accent)}
.tbar b{font-size:15px;font-weight:800;white-space:nowrap}

/* 비교표 */
/* ── 비교표 — 디자이너 시안 (2026-09-10) ────────────────────────────────
   시안은 밝은 표 한 덩어리 옆에 Pre-Sperm 열이 파란 카드로 따로 서 있는 모양입니다.
   둘 다 모서리 40 이라 맞닿는 자리에서 서로 둥글게 갈라집니다.
   열 폭 215 / 287 / 287 / 311 = 1100 (시안 잰 값) */
.cmp{width:1100px;max-width:100%;margin:58px auto 0;
  border-collapse:separate;border-spacing:0;table-layout:fixed}
.cmp td,.cmp th{text-align:center;vertical-align:middle;height:81px;padding:8px 12px;
  font-size:17px;font-weight:400;letter-spacing:-.03em;line-height:1.6}
/* 열 폭은 table-layout:fixed 라 첫 줄이 정합니다 */
.cmp thead td{width:19.55%}
.cmp thead th:nth-child(2),.cmp thead th:nth-child(3){width:26.09%}
.cmp thead th:nth-child(4){width:28.27%}
/* 머리 · 항목명 — 밝은 바닥 */
.cmp thead th,.cmp thead td{height:82px;font-size:20px;font-weight:500;color:var(--t-sub);
  background:#FAFAFA}
.cmp .lab{font-size:20px;font-weight:500;color:var(--t-sub);background:#FAFAFA}
/* 값 — 기존 방식은 흐리게, 우리 것만 또렷하게 */
.cmp .old{color:#9D9D9D;background:#fff}
.cmp .new{font-size:18px;color:#fff;background:var(--brand)}
.cmp thead th:last-child{font-size:20px;color:#fff;background:var(--brand)}
/* 선 — 각 칸이 위·왼쪽을 맡고, 바깥 가장자리만 따로 그립니다 */
.cmp .lab,.cmp .old{border-top:1px solid #ccc;border-left:1px solid #ccc}
.cmp thead td,.cmp thead th:not(:last-child){border-top:1px solid #ccc;border-left:1px solid #ccc}
.cmp tbody tr:last-child .lab,.cmp tbody tr:last-child .old{border-bottom:1px solid #ccc}
/* ★ 구분선은 파란 카드 위로도 지나갑니다 — 시안에서 잰 값입니다.
   머리 아래 줄은 #ccc 그대로, 행 사이는 그 절반 세기로 보입니다 */
.cmp tbody .new{border-top:1px solid rgba(204,204,204,.5)}
.cmp tbody tr:first-child .new{border-top-color:#ccc}
.cmp tbody tr > :nth-child(3){border-right:1px solid #ccc}
.cmp thead th:nth-child(3){border-right:1px solid #ccc}
/* 모서리 40 — 밝은 덩어리와 파란 카드가 각각 둥급니다 */
.cmp thead td{border-top-left-radius:40px}
.cmp thead th:nth-child(3){border-top-right-radius:40px}
.cmp tbody tr:last-child .lab{border-bottom-left-radius:40px}
.cmp tbody tr:last-child > :nth-child(3){border-bottom-right-radius:40px}
.cmp thead th:last-child{border-radius:40px 40px 0 0}
.cmp tbody tr:last-child .new{border-radius:0 0 40px 40px}
/* 표 아래 설명 — 시안은 부제를 짧게 두고 긴 설명을 여기로 내렸습니다 */
.cmp-note{max-width:772px;margin:51px auto 0;font-size:18px;line-height:1.78;
  color:var(--t-sub);text-wrap:pretty;word-break:keep-all}
/* 붙임표(-)는 줄바꿈 자리가 됩니다 — "Pre-Sperm" 이 "Pre-" 에서 끊겼습니다.
   제품 이름은 통째로 묶습니다 */
.nowrap{white-space:nowrap}

/* 등급 */
.grades{display:grid;grid-template-columns:repeat(3,1fr);gap:48px;margin-top:74px;text-align:left}
@media(max-width:820px){.grades{grid-template-columns:1fr;gap:44px}}
.gr .plot{border-radius:14px;overflow:hidden;margin-bottom:22px;aspect-ratio:1/.62;
  background:color-mix(in srgb,var(--fg) 4%, var(--bg));position:relative}
.gr .plot svg{position:absolute;inset:0;width:100%;height:100%}
.gr h4{font-size:17px;font-weight:800;letter-spacing:-.026em;margin-bottom:6px}
.gr .pct{font-size:27px;font-weight:800;letter-spacing:-.035em;line-height:1;margin-bottom:11px}
.gr p{font-size:14px;color:var(--muted);line-height:1.7}

/* 타임라인 */
/* ── 검사 흐름 — 디자이너 시안 (2026-09-10) ─────────────────────────────
   ~~좌: 시간 막대 / 우: 조립 카드~~ -> 유리판 하나 안에 좌: 결과 / 우: 파란 시간 박스.
   바닥이 어두워졌고(--d-flow), 시간은 파란 박스가 됐습니다.
   ★ 연출(뼈대 -> 값, 재생 버튼)은 우리 것을 그대로 씁니다 — JS 는 안 바꿉니다.
     .tl-go / .tl-snap / .tl-rewind 클래스가 그대로 오므로 CSS 만 갈아끼웁니다 */
.tl{flex:none;width:300px;min-height:220px;border-radius:20px;background:var(--brand);
  padding:36px;display:flex;flex-direction:column;justify-content:center;gap:23px}
.tl-row{display:flex;align-items:baseline;justify-content:space-between;gap:16px;
  opacity:0;transform:translateY(7px);
  transition:opacity .45s ease,transform .45s cubic-bezier(.22,.61,.36,1)}
.tl.tl-go .tl-row{opacity:1;transform:none}
.tl.tl-go .tl-row:nth-child(2){transition-delay:.26s}
.tl.tl-go .tl-row:nth-child(3){transition-delay:.52s}
.tl.tl-snap .tl-row{transition:none}
.tl.tl-rewind .tl-row{transition:opacity .3s ease,transform .3s ease}
.tl-row span{font-size:18px;letter-spacing:-.03em;color:rgba(255,255,255,.86)}
.tl-row b{font-size:28px;font-weight:700;letter-spacing:-.03em;color:#fff}

/* 유리판 — 시안 1100 x 310. 뒤 배경이 비치는 반투명 판입니다 */
.flowcard{display:flex;align-items:center;gap:clamp(24px,4vw,96px);
  width:100%;max-width:1100px;margin:56px auto 0;min-height:310px;
  padding:clamp(24px,3vw,60px) clamp(24px,3.4vw,68px);border-radius:24px;
  /* ★ isolation 이 필요합니다 — 아래 ::before 가 z-index:-1 이라, 판이 스스로
     쌓임 맥락을 만들지 않으면 층이 위로 빠져나가 섹션 배경 뒤로 내려갑니다.
     겹침 전환을 걷어내며 #flow 의 position:relative/z-index:2 가 없어지자
     흐림이 통째로 사라졌습니다(09-10). 판이 직접 맥락을 갖게 해 그 의존을 끊습니다 */
  position:relative;isolation:isolate;
  background:rgba(255,255,255,.22);border:1px solid rgba(255,255,255,.16)}
/* ★ 흐림은 별도 층으로 깔고 등장이 끝난 뒤 서서히 켭니다.
   .rev 등장이 조상에 transform 을 거는 동안에는 크롬이 뒤 배경을 흐리게 못 만들어,
   변형이 끝나는 순간 한 번에 적용됐습니다("뙇" — 09-10 사용자 지적).
   backdrop-filter 자체는 전환이 안 되므로 층의 opacity 를 전환합니다.
   z-index:-1 이라 판의 흰 반투명 바닥 **뒤**에 깔립니다 — 흐릴 대상은 섹션 배경입니다.
   지연 .8s = .rev 의 0.8초가 끝나는 바로 그 시점입니다.
   ★ 더 당기면 안 됩니다 — 변형이 남아 있는 동안에는 흐림이 아예 안 걸리고,
     변형이 끝나는 순간 이미 켜져 있던 흐림이 튀어나옵니다(그게 처음 문제였습니다) */
.flowcard::before{content:"";position:absolute;inset:0;border-radius:inherit;z-index:-1;
  opacity:0;backdrop-filter:blur(14px);transition:opacity .5s ease}
.rev.in .flowcard::before{opacity:1;transition-delay:.8s}
@media(prefers-reduced-motion:reduce){
  .flowcard::before{transition:none;opacity:1}
}
  /* ★ 시안의 판은 뒤 그래픽이 밝아서 회색(#4D5058)으로 보입니다. 지금 우리 바닥은
     평평한 검정이라 같은 알파로는 훨씬 어둡습니다 — 보이는 색을 맞춰 0.22 로 올렸습니다.
     배경 캔버스가 들어오면 이 값을 다시 잡아야 합니다 */
.flowcard .asm{flex:1 1 auto;min-width:0;background:none;border:0;padding:0;
  min-height:0;box-shadow:none;transform:none}
/* 총 운동성 게이지 — 시안은 흰 트랙 위 보라 그라디언트입니다.
   ★ 이름이 .gauge 이면 안 됩니다 — 결과 탭이 이미 쓰는 클래스라(초록 채움)
     파일 뒤에 있는 그쪽이 이겨서 초록 막대가 나왔습니다(09-10).
     새 클래스는 grep '.이름' site/assets/css/*.css 로 먼저 확인 — CLAUDE.md */
.fgauge{display:block;width:100%;height:10px;border-radius:100px;
  background:rgba(255,255,255,.9);overflow:hidden}
.fgauge i{display:block;width:78.3%;height:100%;border-radius:100px;
  transform-origin:left;transform:scaleX(0);
  background:linear-gradient(90deg,#fff 0%,var(--violet) 100%);
  transition:transform .85s cubic-bezier(.22,.61,.36,1) .18s}
.asm.on .fgauge i{transform:scaleX(1)}
.asm.asm-snap .fgauge i{transition:none}
@media(max-width:900px){
  .flowcard{flex-direction:column;align-items:stretch;gap:28px;min-height:0}
  .tl{width:auto;min-height:0;padding:24px;gap:16px}
  .tl-row b{font-size:22px}
}
/* ★ 시안은 제목이 화면 가운데입니다. 재생 버튼(우리 것)이 흐름 안에 있으면 제목이
   왼쪽으로 밀립니다 — 버튼만 절대배치로 빼서 오른쪽에 띄웁니다 */
.flow-head{position:relative;display:block;text-align:center}
.flow-head .play{position:absolute;right:0;top:0}
@media(max-width:760px){
  .flow-head .play{position:static;margin-top:16px}
}
.play{display:inline-flex;align-items:center;gap:7px;flex:none;
  background:none;border:1px solid var(--line);border-radius:100px;
  padding:8px 16px 8px 13px;font:inherit;font-size:13px;font-weight:700;
  color:var(--muted);cursor:pointer;transition:color .18s,border-color .18s}
.play:hover{color:var(--fg);border-color:var(--muted)}
.play svg{width:15px;height:15px;fill:currentColor}
.play:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
/* 어두운 섹션 위에서는 밝은 선·글자로 뒤집습니다 */
.s.dark .play{color:rgba(255,255,255,.78);border-color:rgba(255,255,255,.26)}
.s.dark .play:hover{color:#fff;border-color:rgba(255,255,255,.6)}
.s.dark .play:focus-visible{outline-color:#fff}
@media(max-width:760px){.flow-head{flex-direction:column;gap:20px}}

/* 흐름 — 분석 중에는 뼈대가 흐르고, 끝나면 그 자리에서 값으로 바뀝니다.
   ★ 2026-09-10: 어두운 유리판 위로 옮기면서 줄 순서가 바뀌었습니다.
     r1 판정 · r2 게이지 · r3 총 운동성 · r4 분석된 정자 (시안 순서)
     ~~등급 분포 막대 + 범례~~ -> 시안에 없습니다. 그 정보는 결과 화면 탭에 있고,
     게이지 바로 아래 78.3 % 가 글자로 나오므로 색으로만 전달하지도 않습니다 */
.asm{background:none;border:0;padding:0;min-height:0;
  display:flex;flex-direction:column;justify-content:center}
.ar{position:relative}
.ar+.ar{margin-top:clamp(12px,1.8vw,20px)}
.r1{height:36px}.r2{height:10px}.r3{height:36px}.r4{height:22px}
.ar .sk,.ar .ct{position:absolute;inset:0;display:flex;align-items:center;gap:9px;
  transition:opacity .45s,transform .45s cubic-bezier(.22,.61,.36,1)}
.ar .ct{opacity:0;transform:translateY(7px)}
.asm.on .ar .sk{opacity:0;transform:translateY(-5px)}
.asm.on .ar .ct{opacity:1;transform:none}
.asm.on .r2 .sk,.asm.on .r2 .ct{transition-delay:.09s}
.asm.on .r3 .sk,.asm.on .r3 .ct{transition-delay:.18s}
.asm.on .r4 .sk,.asm.on .r4 .ct{transition-delay:.27s}
/* ★ r2 만 제자리에서 바뀝니다 — 이 줄은 높이 10px 짜리 막대라
   7px 을 움직이면 자기 키의 70 % 를 미끄러집니다. 빠지는 뼈대(.sk) 역시
   같은 자리의 막대라, 둘이 위아래로 엇갈려 흔들려 보였습니다(2026-09-10 사용자).
   가로로 차오르는 것(.fgauge i · scaleX)은 그대로 둡니다 — 그쪽이 수치를 말합니다.
   ★ 앞 규칙보다 뒤에 두고 특정도도 한 칸 높였습니다 — CLAUDE.md 반복 함정 ① */
.ar.r2 .ct{transform:none}
.asm.on .ar.r2 .sk{transform:none}
/* 뼈대 — 훑고 지나가는 빛. 어두운 판 위라 흰색 계열로 바꿉니다 */
.sk i{display:block;height:12px;border-radius:100px;
  background:linear-gradient(90deg,
    rgba(255,255,255,.16) 0%, rgba(255,255,255,.06) 45%, rgba(255,255,255,.16) 100%);
  background-size:280% 100%;animation:shim 1.5s linear infinite}
.sk i:nth-child(2){animation-delay:.18s}
@keyframes shim{from{background-position:150% 0}to{background-position:-90% 0}}
.asm .k{font-size:18px;letter-spacing:-.03em;color:rgba(255,255,255,.72)}
/* 판정 글자 — 시안은 게이지와 같은 그라디언트를 글자에 입힙니다
   (잰 값: 왼쪽 #F5F3FE -> 오른쪽 #8B69FE).
   ★ 끝점을 170 % 에 둡니다 — 100 % 로 두면 끝 글자가 #5420FE 까지 어두워져
     유리판 위에서 대비 2.3:1 이 됩니다. 170 % 면 3.1:1 로 큰 글자 기준(3:1)을 넘깁니다 */
.asm .vd{font-size:28px;font-weight:700;letter-spacing:-.03em;color:#fff;
  background-image:linear-gradient(90deg,#fff 0%,var(--violet) 170%);
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;color:transparent}
.asm .r3 .ct{align-items:baseline;gap:6px}
.asm .r3 b{font-size:36px;font-weight:700;letter-spacing:-.03em;line-height:1;color:#fff}
.asm .r3 em{font-style:normal;font-size:18px;font-weight:700;color:#fff;margin-right:6px}
.asm .r4 .ct{align-items:baseline;gap:10px}
.asm .r4 b{font-size:28px;font-weight:700;letter-spacing:-.03em;color:#fff}
/* 스크롤로 다시 들어올 때 — 뼈대로 돌아가는 것을 보여주지 않습니다 */
.asm.asm-snap .ar .sk,.asm.asm-snap .ar .ct{transition:none}
@media(prefers-reduced-motion:reduce){
  .sk i{animation:none}
  .ar .sk,.ar .ct,.asm,.fgauge i,.tl-row{transition:none}
}
@media(max-width:900px){
  .asm .k{font-size:15px}
  .asm .vd{font-size:23px}
  .asm .r3 b{font-size:29px}
  .asm .r4 b{font-size:22px}
  .r1{height:30px}.r3{height:30px}.r4{height:20px}
}

/* 랜딩 추상 결과 카드 */
.mini{background:var(--surface);border:1px solid var(--line);border-radius:16px;padding:24px 26px 22px}
.mini-hd{display:flex;justify-content:space-between;gap:16px;align-items:baseline;
  font-size:12.5px;color:var(--muted);padding-bottom:14px}
.mini-hd span:first-child{color:var(--fg);font-weight:700}
.mini-fn{font-size:11.5px;color:var(--muted);opacity:.75;margin-top:16px;line-height:1.6}
.mini .vd{font-size:30px;font-weight:800;letter-spacing:-.04em;color:var(--ok);line-height:1;
  margin-bottom:18px}
.mini .num{display:flex;align-items:baseline;gap:8px;margin-bottom:6px}
.mini .num b{font-size:34px;font-weight:800;letter-spacing:-.04em;line-height:1}
.mini .num em{font-style:normal;font-size:15px;font-weight:700;color:var(--muted)}
.mini .lab{font-size:13px;color:var(--muted);margin-bottom:18px}

/* 탭 — 판정 / 등급 분포 / 개체 분포 */
/* ── 결과 탭 — 디자이너 시안 (2026-09-10) ────────────────────────────────
   ~~밑줄 탭~~ -> 옅은 알약 바 안에서 고른 탭만 파란 알약이 됩니다.
   시안 잰 값: 바 1200 x 90 · 탭 넷이 1150 을 넷으로 나눔(287.5) · 알약 높이 70 */
.tabs{display:flex;gap:0;margin:0 auto;max-width:1200px;padding:10px;
  border-radius:100px;background:#F5F6F8;border:0}
.tabs button{appearance:none;flex:1;min-width:0;background:none;border:0;
  border-radius:100px;height:70px;
  font-size:clamp(15px,1.5vw,22px);font-weight:700;letter-spacing:-.03em;
  color:#6B6B6B;cursor:pointer;font-family:inherit;
  /* ★ background-color 를 전환 목록에 넣어야 알약이 서서히 물듭니다 —
     빠뜨려서 색이 툭 바뀌었습니다(09-10) */
  transition:color .28s ease,background-color .28s ease}
.tabs button[aria-selected="true"]{color:#fff}
/* 파란 알약 — 색은 transition 이 안 되는 그라디언트가 아니라 단색이라
   background-color 로 전환해도 됩니다 */
.tabs button{background-color:transparent}
.tabs button[aria-selected="true"]{background-color:var(--brand)}
.tabs button:hover:not([aria-selected="true"]){color:var(--t-title)}
.tabs button:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
@media(max-width:760px){
  .tabs{flex-wrap:wrap;border-radius:24px;gap:4px}
  .tabs button{flex:1 1 45%;height:52px;font-size:14px}
}
/* 결과 패널 · 설명 · CTA — 시안은 전부 가운데로 쌓입니다 */
.res-note{max-width:820px;margin:36px auto 0;text-align:center;
  font-size:clamp(15px,1.4vw,19px);line-height:1.7;color:var(--t-sub)}
.res-cta{display:flex;justify-content:center;margin-top:28px}
/* ★ 탭마다 높이가 다르면 눌렀을 때 카드가 늘었다 줄었다 합니다.
   패널이 1180 으로 넓어지면서 산점도가 그대로 커져 686px(두 배)이 됐습니다.
   그림마다 최대 폭을 정해 네 탭의 높이를 맞춥니다 */
/* 탭을 바꿔도 카드 높이가 흔들리지 않게 바닥을 깔아 둡니다.
   ★ 2026-09-10: 가장 높은 탭(개체 분포)에 맞춰 354 로 올렸습니다 */
.tabbody{min-height:354px;display:flex;flex-direction:column;justify-content:center;
  transition:opacity .2s ease, transform .2s ease}
/* 탭 전환 — 나가는 것은 위로 걷히고, 들어오는 것은 아래에서 올라옵니다 */
.tabbody.leaving{opacity:0;transform:translateY(-7px)}
.tabbody.entering{opacity:0;transform:translateY(9px);transition:none}
/* ★ 막대·게이지는 조상의 .in 에 묶여 있어, 새로 그리면 이미 끝난 상태로 삽입됩니다.
   한 프레임 동안 0 으로 붙들었다 놓아야 다시 자랍니다. */
.tabbody.hold .bar i,.tabbody.hold .gauge i{transform:scaleX(0);transition:none}
@media(prefers-reduced-motion:reduce){
  .tabbody,.tabbody.leaving,.tabbody.entering{transition:none;opacity:1;transform:none}}

.tabbody .sc{width:100%;height:auto;margin:0;display:block}

/* 등급 분포 막대 — 구간 사이에 바닥색 선을 하나 긋습니다.
   전진(초록)과 비전진(주황)의 밝기 대비가 1.06:1 이라 색상만으로 갈립니다.
   강제 다크·색약·흑백 인쇄에서 두 구간이 붙어 보이던 원인이 이것입니다.
   box-shadow 라 레이아웃이 한 픽셀도 안 바뀝니다(gap 을 쓰면 총합이 100 %를 넘습니다).
   ★ 2026-09-10 복구 — CSS 를 지울 때 범위를 잘못 잡아 이 줄이 같이 날아갔습니다 */
.bar>i+i,.dist>i+i{box-shadow:-1.5px 0 0 var(--surface)}

/* 기준선이 붙는 게이지 */
.gauge{position:relative;height:9px;border-radius:100px;background:var(--ghost);overflow:hidden}
.gauge i{position:absolute;inset:0 auto 0 0;border-radius:100px;background:var(--ok);
  transform-origin:left;transform:scaleX(0);transition:transform .9s cubic-bezier(.22,.61,.36,1)}
.in .gauge i{transform:scaleX(1)}
.gauge u{position:absolute;top:-3px;bottom:-3px;width:2px;background:var(--fg);opacity:.55}
.gwrap{position:relative;padding-bottom:24px}
.gth{position:absolute;top:15px;transform:translateX(-50%);white-space:nowrap;
  font-size:11.5px;color:var(--muted)}
.barwrap{position:relative;padding-bottom:24px}
.barwrap u{position:absolute;top:-3px;height:15px;width:2px;background:var(--fg);opacity:.55}
.tabbody .bar{margin-bottom:2px}

/* 판정 탭의 지표 세 줄 */
.mets{margin-top:22px;border-top:1px solid var(--line)}
.mets div{display:flex;justify-content:space-between;gap:20px;align-items:baseline;
  padding:10px 0;border-bottom:1px solid var(--line);font-size:13px}
.mets div:last-child{border-bottom:0}
/* ── 목록형 행 호버 (비교표 행에서 시작한 규칙) ──────────────────────
   글자에 딱 붙은 하이라이트는 답답합니다. 행 자체에 좌우 여백을 주면
   구분선까지 같이 넓어져 위쪽 선과 어긋나므로, 배경만 뒤에 깔아 넓힙니다.
   레이아웃은 한 픽셀도 바뀌지 않습니다. */
.mets div,.rc,.glist div{position:relative;isolation:isolate}
.mets div > *,.rc > *,.glist div > *{position:relative;z-index:1}
.mets div::before,.rc::before,.glist div::before{content:"";position:absolute;
  inset:2px -14px;border-radius:9px;background:transparent;z-index:0;
  transition:background .18s ease}
.mets div:hover::before,.rc:hover::before,.glist div:hover::before{
  background:color-mix(in srgb,var(--fg) 3.5%, transparent)}
.mets .k{color:var(--muted)}
.mets .v{font-weight:700}
.mets .v small{font-weight:600;color:var(--muted);font-size:11.5px;margin-left:3px}

/* 등급 분포 */
.glist{margin-top:8px}
.glist div{display:grid;grid-template-columns:12px 1fr auto;gap:10px;align-items:center;
  padding:14px 0;border-bottom:1px solid var(--line);font-size:13.5px}
.glist div:last-child{border-bottom:0}
.glist i{width:12px;height:12px;border-radius:4px}
.glist b{font-weight:700;font-variant-numeric:tabular-nums}
.glist em{font-style:normal;display:block;font-size:11.5px;color:var(--muted);font-weight:400}

/* 개체 분포 산점도 */
.sc{position:relative}
.sc svg{width:100%;height:auto;display:block}
.sc .ax{fill:var(--muted);font-size:10.5px}
.sc .gl{stroke:var(--line)}
.sc .pr{fill:var(--ok);opacity:.5}
.sc .np{fill:none;stroke:var(--warn);stroke-width:1.3}
.sc .hit{fill:none;stroke:var(--fg);stroke-width:1.6;opacity:0;transition:opacity .12s}
.sc .hit.on{opacity:1}
/* 등장 — 축과 격자는 먼저 서 있고, 점이 화면 곳곳에서 흩뿌려지듯 떠오른 뒤
   평균 십자선이 얹힙니다. 점은 shell.js 에서 묶음 열 개에 무작위로 나눠 담기므로
   묶음마다 시차만 주면 됩니다 — 943개가 아니라 열 개만 움직입니다. */
/* ★ 랜딩(#land)에서만 재생합니다. 산점도는 shell.js 의 공용 함수라
   대시보드 검사 결과에도 같은 마크업이 들어가는데, 거기서는 그 그래프 하나만
   혼자 떠올라 어색합니다(사용자 지적 2026-09-08).
   이 연출은 결과 탭 전환에서 랜딩 탭을 위해 만든 것입니다. */
@keyframes scPop{from{opacity:0}to{opacity:1}}
#land .sc .scd{animation:scPop .22s ease both}
#land .sc .b0{animation-delay:0s}    #land .sc .b1{animation-delay:.04s}
#land .sc .b2{animation-delay:.08s}  #land .sc .b3{animation-delay:.12s}
#land .sc .b4{animation-delay:.16s}  #land .sc .b5{animation-delay:.2s}
#land .sc .b6{animation-delay:.24s}  #land .sc .b7{animation-delay:.28s}
#land .sc .b8{animation-delay:.32s}  #land .sc .b9{animation-delay:.36s}
#land .sc .scm{animation:scPop .4s ease .62s both}
@media(prefers-reduced-motion:reduce){
  #land .sc .scd,#land .sc .scm{animation:none;opacity:1}}
.sc-tip{position:absolute;pointer-events:none;opacity:0;transform:translate(-50%,-100%);
  background:var(--fg);color:var(--bg);font-size:11.5px;line-height:1.5;font-weight:600;
  padding:6px 9px;border-radius:8px;white-space:nowrap;transition:opacity .12s}
.sc-tip.on{opacity:1}

/* 활력 예측 등장 — 데이터가 왼쪽에서 오른쪽으로 드러납니다.
   ★ 선을 dashoffset 으로 그리는 흔한 방법은 못 씁니다 — 예측선이 이미 점선
     (stroke-dasharray:6 5)이라 패턴이 서로 부딪힙니다. 묶음을 좌->우로 여는 방식입니다.
   ★ 축·격자·축 이름은 묶음 밖이라 처음부터 제자리에 있습니다.
     호버 층도 밖입니다 — 클립 안에 있으면 손을 올려도 안 보입니다.
   ★ 랜딩에서만 겁니다(#land). 대시보드 카드는 지금 동작 그대로입니다.
   ~~덮개만 따로 걷는 방식~~ -> 2026-09-10 되돌림(사용자):
     데이터와 덮개 두 가장자리가 서로 다른 속도로 움직여 "주체가 둘" 로 보였습니다 */
#land .fc-data{clip-path:inset(0 100% 0 0);
  transition:clip-path .95s cubic-bezier(.22,.61,.36,1) .05s}
#land .in .fc-data{clip-path:inset(0 0 0 0)}
#land .tabbody.hold .fc-data{clip-path:inset(0 100% 0 0);transition:none}
@media(prefers-reduced-motion:reduce){
  #land .fc-data{clip-path:none;transition:none}
}

/* 활력 예측 탭은 shell.js 의 forecastChart 를 그대로 씁니다 —
   그림·호버·범례가 대시보드와 한 벌입니다. 별도 CSS 가 필요 없습니다 */

/* ── 말풍선 ──────────────────────────────────────────────────────────
   브라우저 기본 툴팁(title)을 대신합니다. 늦게 뜨지 않고, 모양과 위치를
   우리가 정하며, 다크 모드에서도 반전됩니다(--fg/--bg 를 그대로 씀).
   position:fixed 라 굴러가는 표 안에서도 잘리지 않습니다. */
/* ★ 말풍선은 절대 포인터를 받지 않습니다. 한때 설명형에만 pointer-events:auto 를
   줬는데, 닫아도 그 자리에 투명한 카드가 남아 아래의 다른 물음표를 먹었습니다
   — 커서가 기본 화살표로 바뀌고 클릭이 안 되던 것이 이것입니다(09-07).
   툴팁 안에는 누를 것을 넣지 않는다는 것이 관례이기도 합니다(Carbon). */
.bub{position:fixed;z-index:60;pointer-events:none;opacity:0;
  background:var(--fg);color:var(--bg);border-radius:10px;padding:9px 12px;
  font-size:11.5px;line-height:1.7;font-weight:600;white-space:nowrap;
  box-shadow:0 16px 34px -14px rgba(0,0,0,.55);
  transition:opacity .14s ease, transform .16s ease}
/* 상자째 미끄러져 들어옵니다(꼬리도 같이). 여기에 transform 을 걸 수 있는 것은
   자리를 잡을 때 크기를 offsetWidth/offsetHeight 로 재기 때문입니다 —
   getBoundingClientRect 로 재면 변형된 값이 나와 위치·꼬리가 어긋납니다. */
.bub{transform:translateY(3px)}
.bub.under{transform:translateY(-3px)}
.bub.on,.bub.under.on{opacity:1;transform:none}
/* 꼬리 */
.bub::after{content:"";position:absolute;top:100%;left:var(--ax,50%);margin-left:-5px;
  box-sizing:border-box;border:5px solid transparent;border-top-color:var(--fg)}
.bub.under::after{top:auto;bottom:100%;border-top-color:transparent;
  border-bottom-color:var(--fg)}
.bub .row{display:flex;align-items:center;gap:8px}
.bub .row i{width:7px;height:7px;border-radius:2px;display:block;flex:none}
.bub .row b{margin-left:auto;font-weight:800;font-variant-numeric:tabular-nums}

/* 설명형 — 눌러서 여는 말풍선(toggletip). 문장이 길어 대비보다 읽기가 우선이라
   Material 3 의 rich tooltip 처럼 일반 surface 를 씁니다. */
.bub.rich{background:var(--surface);color:var(--fg);border:1px solid var(--line);
  white-space:normal;width:max-content;max-width:min(290px,calc(100vw - 24px));
  font-size:13px;font-weight:400;line-height:1.72;padding:13px 15px;text-align:left;
  box-shadow:0 22px 44px -18px rgba(0,0,0,.35)}
.bub.rich b{font-weight:700}
/* 꼬리 — 삼각형 대신 회전한 사각형이라야 테두리가 이어집니다 */
.bub.rich::after{box-sizing:border-box;border:1px solid var(--line);
  border-top:0;border-left:0;background:var(--surface);width:10px;height:10px;
  transform:rotate(45deg);top:auto;bottom:-6px;margin-left:-5px;
  left:var(--ax, 50%)}
.bub.rich.under::after{top:-6px;bottom:auto;border:1px solid var(--line);
  border-bottom:0;border-right:0}

/* 물음표 — 표 안의 용어 옆에 붙습니다.
   좁은 화면에서 셀이 flex 로 바뀌므로 용어와 한 덩어리로 묶어 둡니다 */
.qterm{display:inline-flex;align-items:center}
/* ★ 글자를 line-height 로 가운데 맞추면 서체 지표에 휘둘립니다 — A2Z 로 바꾸면서
   물음표가 원 안에서 미묘하게 어긋났습니다(09-10 사용자 지적).
   flex 로 맞추고 line-height 를 1 로 두면 서체와 무관하게 가운데에 옵니다 */
.qm{margin-left:6px;width:16px;height:16px;padding:0;border:0;border-radius:50%;
  display:inline-flex;align-items:center;justify-content:center;
  background:color-mix(in srgb,var(--muted) 22%, transparent);color:var(--muted);
  font:inherit;font-size:10.5px;font-weight:800;line-height:1;letter-spacing:0;
  cursor:pointer;vertical-align:middle;transition:background .16s ease,color .16s ease;
  /* ★ 표 셀이 가운데 정렬이라 버튼이 매번 소수점 좌표에 앉습니다(x 소수 .89/.66/.25).
     그 상태에서 LCD 서브픽셀로 글자를 그리면 화소마다 색 번짐이 달라져
     물음표가 원 안에서 서로 다른 위치처럼 보입니다(09-10 사용자 지적).
     회색조로 그리게 해서 위치에 따른 차이를 줄입니다 */
  }
/* ── 물음표가 원 안에서 어긋나 보이던 것 (2026-09-10) ─────────────────
   원인 둘을 재서 갈랐습니다.
     ① 세로 정렬을 line-height 로 하던 것 -> flex 로 바꿔 해결(세 개가 화소까지 동일)
     ② 표가 가운데 정렬이라 버튼이 소수점 x 에 앉습니다(.89 / .66 / .25).
        그 상태의 LCD 서브픽셀 렌더링은 화소마다 색 번짐이 달라, 확대하면 같은데
        실제 크기에서는 미세하게 달라 보입니다. **여기까지가 한계입니다**
   시도했다가 되돌린 것
     -webkit-font-smoothing:antialiased  Windows 크롬에서 무효(재서 확인). macOS 전용
     SVG 도형으로 교체                    물음표로 안 읽혀서 되돌렸습니다(사용자) */
.qm:hover,.qm[aria-expanded="true"]{background:var(--accent);color:var(--on-accent)}
.qm:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
/* ★ 파란 카드 위에서는 --muted 기반 색이 묻힙니다 (09-10 사용자 지적).
   흰 글자 대 #0143B7 은 8.4:1 이라 대비도 넉넉합니다 */
.cmp .new .qm{background:transparent;color:#fff;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.55)}
.cmp .new .qm:hover,.cmp .new .qm[aria-expanded="true"]{background:#fff;color:var(--brand);
  box-shadow:none}
.cmp .new .qm:focus-visible{outline-color:#fff}
/* 집히는 범위는 넓히고 보이는 크기는 그대로 (WCAG 2.5.8) */
.qm{position:relative}
.qm::after{content:"";position:absolute;inset:-6px}
@media(prefers-reduced-motion:reduce){.bub{transition:opacity .14s ease;transform:none}}
.sc-lg{display:flex;flex-wrap:wrap;gap:6px 18px;align-items:center;margin-top:14px;
  font-size:12px;color:var(--muted)}
.sc-lg span{display:flex;align-items:center;gap:6px}
.sc-lg b{color:var(--fg);font-weight:700;font-variant-numeric:tabular-nums}
.sc-lg .d{width:9px;height:9px;border-radius:50%;background:var(--ok);opacity:.6}
.sc-lg .o{width:9px;height:9px;border-radius:50%;border:1.4px solid var(--warn)}
.bar{display:flex;height:9px;border-radius:100px;overflow:hidden}
.bar i{transform-origin:left;transform:scaleX(0);
  transition:transform .9s cubic-bezier(.22,.61,.36,1)}
.in .bar i{transform:scaleX(1)}
.in .bar i:nth-child(2){transition-delay:.12s}
.in .bar i:nth-child(3){transition-delay:.24s}

/* 작업 영역 결과 카드 */
.result{background:var(--surface);border:1px solid var(--line);border-radius:18px;padding:32px}
.res-id{display:flex;justify-content:space-between;gap:14px;font-size:12.5px;
  color:var(--muted);margin-bottom:24px}
.verdict{font-size:44px;font-weight:800;letter-spacing:-.045em;color:var(--ok);
  line-height:1;margin-bottom:8px}
.verdict-sub{font-size:14px;color:var(--muted);margin-bottom:30px}
.hl{display:flex;align-items:baseline;gap:10px;margin-bottom:6px}
.hl b{font-size:52px;font-weight:800;letter-spacing:-.045em;line-height:1}
.hl em{font-style:normal;font-size:18px;font-weight:700;color:var(--muted)}
.hl-lab{font-size:13.5px;color:var(--muted);margin-bottom:24px}
.legend{display:flex;flex-wrap:wrap;gap:20px;font-size:13px;margin:13px 0 28px}
.legend span{display:inline-flex;align-items:center;gap:7px;color:var(--muted)}
.legend b{color:var(--fg)}
.legend i{width:8px;height:8px;border-radius:2px;display:block}
/* ★ 2026-09-14 — 윗선을 뺐습니다. 쓰는 네 곳이 전부 style="border-top:0" 으로
   지우고 있었습니다(인라인으로 기본값을 덮는 상태). 기본값을 쓰임에 맞춥니다.
   ★ 마지막 줄의 아랫선도 뺍니다 — 카드 테두리가 이미 아래를 닫고 있어
   선이 겹쳐 떠 보입니다. "목록의 마지막 항목에는 구분선을 넣지 않는다" 가 관례입니다
   (Material Design Dividers). 사용자가 `현황`(선 없음)과 `요약`(선 있음)의
   차이로 잡아낸 건입니다 */
.metrics{border-top:0}
.metrics .m:last-child{border-bottom:0}
.m{display:flex;justify-content:space-between;align-items:baseline;gap:14px;
  padding:14px 0;border-bottom:1px solid var(--line);font-size:15px}
.m .k{color:var(--muted)}.m .v{font-weight:700}
.m .r{color:var(--muted);font-weight:400;font-size:12.5px;margin-left:9px}
.m .none{color:var(--muted);font-weight:400}

.orgs{display:flex;flex-wrap:wrap;justify-content:center;gap:34px;margin-top:62px}
.org{font-size:15px;font-weight:700;color:var(--muted)}
.claims{display:grid;grid-template-columns:repeat(3,1fr);gap:44px;margin-top:64px;text-align:left}
@media(max-width:820px){.claims{grid-template-columns:1fr;gap:32px}}
.claim b{display:block;font-size:16px;font-weight:800;letter-spacing:-.022em;margin-bottom:8px}
.claim p{font-size:14px;color:var(--muted);line-height:1.72}

/* ── CTA — 시안 (2026-09-10) ───────────────────────────────────────────
   배경은 디자이너 에셋입니다. 원본 7680x1520(4배, 6.4MB) -> 2560x507 webp 43KB.
   원본은 저장소 밖에 보관합니다.
   4배 배율이라 시안의 CTA 띠는 **1920 x 380** 입니다 — 캡처로 잰 400 은 5 % 틀렸습니다.
   그래서 여백을 112 로 잡아 띠를 380 에 맞춥니다. 1920 에서 그림이 1:1 로 들어갑니다.

   ★ 덮개를 안 씌웁니다. #flow 는 원본이 밝아 검정 50 % 를 얹었지만, 이 그림은
     이미 어둡습니다 — 평균 밝기 18.6 · 상위 10 % 47 로, 덮개를 씌운 뒤의
     flow(17.8 / 44.0)와 사실상 같습니다. 더 덮으면 파도가 사라집니다.

   ★ cover 를 쓰지 않습니다. 재보니 밝은 것이 좌우 끝에 몰려 있어
     (왼쪽 12 % 평균 34.2 · 가운데 25 % 13.5 · 오른쪽 12 % 8.4),
     cover 는 1920 보다 좁은 모든 화면에서 폭을 잘라 그 파도를 먼저 버립니다.
     대신 **폭을 항상 다 쓰고 아래를 기준으로 붙입니다**:
       넓은 화면  그림이 띠보다 높아 위가 잘립니다 — 위쪽은 원래 검정입니다
                (맨 위 10 % 평균 RGB 0,2,4 · --d-cta 는 1,6,10 이라 이어집니다)
       좁은 화면  그림이 띠보다 낮아 아래에 깔립니다. 위는 같은 검정이라 티가 안 납니다
     좌우가 한 번도 안 잘리므로 파도가 어느 폭에서도 남습니다 */
/* ★ 2026-09-15 — #flow 와 같은 이유로 그림만 `.bgnear` 로 내렸습니다.
   여백(112.5px)은 배치라 기본값에 둡니다 — 그림이 늦게 와도 높이가 안 흔들립니다 */
.cta{background-color:var(--d-cta);padding:112.5px 0}
.cta.bgnear{
  background-image:url("../img/cta-bg.webp");
  background-size:100% auto;background-position:center bottom;background-repeat:no-repeat}
.cta .d2{color:#fff;margin-bottom:38px}
.cta .btns{display:flex;justify-content:center}
/* 시안의 CTA 버튼은 흰 테두리에 속이 빈 알약입니다 — 히어로의 보라 테두리와 다릅니다.
   hover 는 시안에 없어서 히어로와 같은 방식(테두리 색으로 채우기)을 흰색으로 씁니다.
   ★ .btn.on-dark 와 특정도가 같으면 파일 뒤가 이기는 자리라, 한 칸 높여 못박습니다 */
.cta .btn.on-dark{box-shadow:inset 0 0 0 1px rgba(255,255,255,.8)}
.cta .btn.on-dark::before{background-image:linear-gradient(#fff,#fff)}
.cta .btn.on-dark:hover{color:var(--d-cta)}
/* 여백은 시안 값이 상한 — 좁은 폭에서만 줄입니다 (반응형 원칙 ④) */
@media(max-width:900px){.cta{padding:90px 0}.cta .d2{margin-bottom:32px}}
@media(max-width:640px){.cta{padding:68px 0}.cta .d2{margin-bottom:26px}}
/* ── footer — 시안 (2026-09-10) ────────────────────────────────────────
   캡처에서 잰 값(배율 1.3588 · 잉크높이 ≈ 글자크기로 보정. 아는 값 제목 36px -> 잉크 37).
     띠 전체       1368~1679 = 311 높이 · 바닥 --d-foot #000
     로고          잉크 1448~1492 (44px) · 폭 262
     회사/주소·로그인 잉크 1511~1529 (18px)
     구분선        1583 · 1200 폭을 다 씁니다
     저작권·방침     잉크 1607~1622 (15px)
   ★ 글자는 전부 흰색입니다 — 작은 줄이 회색으로 보이는 것은 획이 얇아서지 색이 아닙니다
     (가장 밝은 픽셀이 다 rgb 255,255,255. 구분선만 rgb 96,96,96).
   ★ 글자는 1200 안에서 좌우 27px 더 들어가 있고, 구분선만 1200 을 꽉 씁니다 */
/* ★ 2026-09-11 시안 실측으로 교체 — 내부 간격은 시안 프레임 그대로입니다.
   로고 40(48) → 20 → 회사줄 22 → 53 → 구분선 → 22 → 저작권 18.
   시안 footer 프레임은 203 이고 그 아래로 검은 영역이 48 더 있습니다.
   바깥 여백은 그 48 을 위아래로 씁니다 — 프레임 위쪽 경계는 CTA 배경과
   맞물려 있어 시안에서 단정할 수 없었습니다 */
.foot{background:var(--d-foot);color:#fff;padding:48px 0}
.foot-in{padding:0 25px}   /* 시안: 구분선 1200 · 텍스트 1150 -> 안쪽 25 */
.foot-top{display:flex;justify-content:space-between;align-items:flex-end;gap:24px}
.foot-logo{font-size:40px;font-weight:700;letter-spacing:-.02em;line-height:1.2}
.foot-co{margin-top:20px;font-size:18px;letter-spacing:-.02em;line-height:1.2}
.foot-co .addr{font-size:16px}   /* 시안: 회사명 18 · 구분막대와 주소 16 */
/* 회사와 주소 사이 세로 막대 — 글자로 넣으면 낭독기가 읽습니다 */
.foot-co i{display:inline-block;width:1px;height:13px;margin:0 20px;vertical-align:-1px;
  background:rgba(255,255,255,.45)}
.foot-login{color:#fff;font-size:18px;font-weight:700;letter-spacing:-.02em;
  text-decoration:none}
.foot-login:hover{text-decoration:underline}
.foot-line{border:0;height:1px;background:rgba(255,255,255,.38);margin:53px 0 22px}
.foot-bot{display:flex;justify-content:space-between;align-items:baseline;gap:24px;
  font-size:15px;letter-spacing:-.02em;line-height:1.2}
.foot-bot small{font-size:inherit}
.foot-priv{font-weight:500;color:inherit;text-decoration:none}   /* 시안: A2Z 5 Medium */
.foot-priv:hover{text-decoration:underline}
@media(max-width:760px){
  .foot{padding:56px 0 40px}
  .foot-in{padding:0}
  .foot-logo{font-size:34px}
  .foot-co,.foot-login{font-size:16px}
  .foot-co i{margin:0 12px}
  .foot-bot{flex-direction:column;align-items:flex-start;gap:10px;font-size:13.5px}
  .foot-line{margin:34px 0 18px}
}
@media(max-width:430px){
  .foot-co{display:flex;flex-direction:column;gap:4px}
  .foot-co i{display:none}
}

/* ~~.work{padding:44px 0 120px} · .work-grid~~ -> 2026-09-14 삭제.
   옛 목업에서 결과 화면을 감싸던 **섹션** 클래스였는데 지금은 쓰는 마크업이 없습니다.
   ★ 그런데 랜딩 시안 반영이 서체를 대시보드에서만 되돌리려고 app.html 에 `<body class="work">` 를
     붙이면서(위 17줄 주석), body 가 이 padding 을 물어 **대시보드 맨 위에 빈 띠 44px**
     이 생겼습니다 — 랜딩 작업이 만든 회귀입니다.
   `body.work` 는 서체 전용으로 계속 씁니다(65줄). 레이아웃 규칙만 지웁니다 */
.panel{background:var(--surface);border:1px solid var(--line);border-radius:18px;padding:24px}
.panel h3{font-size:12px;font-weight:700;letter-spacing:.07em;color:var(--muted);margin-bottom:16px}
.shotbox{border-radius:12px;overflow:hidden;border:1px solid var(--line)}
.cap{font-size:12.5px;color:var(--muted);margin-top:12px;line-height:1.65}
/* ── 섹션 제목 — 명사형 제목 + 설명 한 덩어리 ── */
/* ── 섹션 제목 — 시안 Section/Title 컴포넌트 (2026-09-10) ────────────────
   제목 A2Z Bold 36 · 부제 A2Z Regular 28 · 사이 16 · 가운데 정렬.
   시안이 이 컴포넌트를 여섯 섹션에 모두 씁니다. 좁은 폭에서만 줄입니다(원칙 ③) */
.sec-head{margin-bottom:56px}
.sec-head .d2{margin-bottom:16px;font-size:clamp(24px,2.9vw,36px);font-weight:700;
  letter-spacing:-.03em;line-height:1.3;color:var(--t-title)}
/* ★ 시안은 28px 인데 실제 화면에서 과했습니다(09-10 사용자). 상한을 21 로 낮춥니다 */
.sec-sub{font-size:clamp(14.5px,1.6vw,21px);font-weight:400;letter-spacing:-.03em;
  line-height:1.35;color:var(--t-sub);max-width:none}
.center .sec-sub{margin-left:auto;margin-right:auto}
.sec-head.tight{margin-bottom:34px}
.sec-head.tight .d2{margin-bottom:14px}
.sec-head.tight .sec-sub{font-size:15px;max-width:40ch}
@media(max-width:760px){.sec-head{margin-bottom:40px}}

/* ── 비교표를 카드로 띄웁니다 ── */
/* ★ 껍데기는 비웁니다 — 시안에서는 표 자신이 모서리와 테두리를 갖습니다.
   .cmp-card 는 등장 애니메이션(.rev)의 그릇으로만 남습니다 */
.cmp-card{background:none;border:0;border-radius:0;overflow:visible;box-shadow:none;
  margin-top:0}
.cmp-card .cmp{margin-top:58px}
/* 좁아지면 시안 값(20/18/17)이 그대로는 안 들어갑니다 — 상한으로 두고 줄입니다
   (반응형 원칙 ③) */
@media(max-width:1100px){
  .cmp td,.cmp th{font-size:15.5px;height:70px;padding:8px 8px}
  .cmp thead th,.cmp thead td,.cmp .lab{font-size:16.5px}
  .cmp .new,.cmp thead th:last-child{font-size:16.5px}
  .cmp thead th,.cmp thead td{height:70px}
}
@media(max-width:820px){
  .cmp td,.cmp th{font-size:14px;height:62px}
  .cmp thead th,.cmp thead td,.cmp .lab,.cmp .new,.cmp thead th:last-child{font-size:14.5px}
  .cmp thead th,.cmp thead td{height:62px}
  .cmp thead td,.cmp thead th:nth-child(3),.cmp tbody tr:last-child .lab,
  .cmp tbody tr:last-child > :nth-child(3){border-radius:0}
  .cmp thead td{border-top-left-radius:24px}
  .cmp thead th:nth-child(3){border-top-right-radius:24px}
  .cmp tbody tr:last-child .lab{border-bottom-left-radius:24px}
  .cmp tbody tr:last-child > :nth-child(3){border-bottom-right-radius:24px}
  .cmp thead th:last-child{border-radius:24px 24px 0 0}
  .cmp tbody tr:last-child .new{border-radius:0 0 24px 24px}
  .cmp-note{font-size:16px;margin-top:36px}
}
/* 좁은 화면에서는 4열을 우겨넣지 않고 항목마다 카드 한 장으로 풉니다.
   330px 에서는 셀마다 두 줄로 접혀 표가 표 구실을 못 합니다. */
@media(max-width:640px){
  .cmp-card{border-radius:16px;background:var(--surface);border:1px solid var(--line);
    overflow:hidden}
  /* ★ .cmp-card .cmp{margin-top:58px} 이 특정도에서 이겨 카드 안에 58px 공백이
     남아 있었습니다(2026-09-11 사용자). 카드로 풀리면 표에 위 여백이 필요 없습니다 */
  .cmp,.cmp-card .cmp{width:auto;margin-top:0;table-layout:auto}
  .cmp-card .cmp,.cmp-card .cmp tbody,.cmp-card .cmp tr,.cmp-card .cmp td{display:block;width:auto}
  .cmp-card .cmp thead{display:none}
  .cmp-card .cmp tr{padding:16px 18px 14px}
  .cmp-card .cmp tr+tr{border-top:1px solid var(--line)}
  .cmp-card .cmp td{padding:6px 0;display:flex;gap:14px;align-items:baseline;
    justify-content:space-between;font-size:14.5px;text-align:right}
  .cmp-card .cmp td::before{content:attr(data-h);font-size:12.5px;color:var(--muted);
    font-weight:400;flex:none;text-align:left}
  .cmp-card .cmp .lab{padding:0 0 9px;font-size:13px;font-weight:800;color:var(--fg);
    display:block;text-align:left}
  .cmp-card .cmp .lab::before{content:none}
  .cmp-card .cmp .new{background:none;font-weight:700;color:var(--brand);font-size:14.5px}
  .cmp-card .cmp tbody tr:hover{background:none}
  /* ★ 데스크톱 표의 선·모서리를 전부 지웁니다.
     카드로 풀린 상태에서 가로선 한 줄이나 둥근 모서리가 남으면 뜬금없이 보입니다.
     :first-child · :last-child 를 같이 적는 이유는 820px 블록의 같은 셀렉터가
     더 세기 때문입니다 — 같은 특정도로 맞추고 파일 뒤에 두어야 이깁니다 */
  .cmp-card .cmp tbody tr > *,
  .cmp-card .cmp tbody tr:first-child > *,
  .cmp-card .cmp tbody tr:last-child > *{border:0;border-radius:0;background:none;
    height:auto}
  /* 물음표 — 파란 바닥이 아니라 흰 바닥이므로 원래 방식으로 되돌립니다 */
  .cmp-card .cmp .new .qm{background:color-mix(in srgb,var(--brand) 15%, transparent);
    color:var(--brand);box-shadow:none}
  .cmp-card .cmp .new .qm:hover,.cmp-card .cmp .new .qm[aria-expanded="true"]{
    background:var(--brand);color:#fff}
}

/* ── 근거 섹션 ── */
/* 시안(2026-09-10) — 흰 판 하나 + 그 아래 파란 띠. 각주는 판 안 오른쪽 아래입니다.
   ★ 판 안의 그림(혼동행렬·재현율)은 시안이 우리 화면을 캡처해 확대한 것입니다
 예외: 그림은 실제 구현을 그대로 쓰고 껍데기만 시안으로 바꿉니다.
   잰 값 — 캡처 1,411px = 시안 1,920px(배율 1.361) 기준:
     흰 판 1200x448 · 파란 띠 높이 146 · 둘 사이 30 · 모서리 24 */
.ev-card{background:var(--surface);border-radius:24px;padding:42px 48px 40px}
/* 각주 — 시안대로 판 오른쪽 아래입니다.
   ★ 흐름에 그냥 두면(판 밑에 한 줄 더) 판이 40px 쯤 다시 높아집니다.
     재현율 칸이 혼동행렬보다 짧아 아래가 비어 있으므로, 그 칸을 판 높이만큼
     늘리고 각주를 바닥으로 밀어냅니다 — 높이가 한 픽셀도 안 늘어납니다.
     재현율 칸의 오른쪽 끝 = 판 안쪽 오른쪽 끝이라 우하단으로 앉습니다 */
.recall{display:flex;flex-direction:column;align-self:stretch}
.ev-fn{margin-top:auto;padding-top:26px;text-align:right;
  font-size:12.5px;color:var(--muted);line-height:1.7}
/* 한 칸으로 접히면 각주가 갈 '오른쪽 아래'가 없습니다 — 재현율 밑에 그대로 붙습니다 */
@media(max-width:860px){.ev-fn{text-align:left;padding-top:22px}}

/* ★ gap 을 0 으로 못박습니다 — 여백이 있으면 칸이 띠보다 좁아져 hover 가
   띠 안쪽 네모에만 칠해집니다. 실제로 옛 규칙의 gap:64px 가 새어 들어와 그랬습니다(09-10) */
/* ★ 2026-09-11 — TalkToFigma 로 시안을 직접 읽어 값을 맞췄습니다.
   그전 값은 캡처에서 잉크 높이로 역산한 것이라 전부 조금씩 틀렸습니다.
   시안 실측: 띠 1200x150 radius 24 · 안쪽 블록 1060x80(= 상하 여백 35) ·
             칸 300x74 · 구분선은 띠 전체가 아니라 높이 80 짜리 짧은 선 ·
             수치 30 Bold(700) ls -2 % · 라벨 18 Regular ls -2 % */
.ev{display:grid;grid-template-columns:repeat(3,1fr);gap:0;align-items:stretch;
  margin-top:30px;min-height:150px;background:var(--brand);border:0;border-radius:24px;
  overflow:hidden;text-align:center;color:#fff}
/* 칸이 띠 높이를 다 쓰고, 내용은 칸 안에서 가운데로 — hover 가 띠 끝까지 칠해집니다 */
.ev > div{position:relative;background:none;padding:35px 24px;
  display:flex;flex-direction:column;justify-content:center}
/* 칸 사이 세로선 — 시안은 띠를 가로지르지 않고 내용 높이(80)만큼만 섭니다.
   inset 그림자로는 길이를 못 정해서 가상 요소로 그립니다 */
.ev > div + div::before{content:"";position:absolute;left:0;top:50%;
  transform:translateY(-50%);width:1px;height:80px;background:rgba(255,255,255,.3)}
.ev .num{font-size:clamp(22px,2.2vw,30px);font-weight:700;letter-spacing:-.02em;
  line-height:1.3;margin-bottom:8px;color:#fff}
.ev .num small{font-size:.62em;font-weight:700;margin-left:1px}
.ev p:last-child{font-size:clamp(14px,1.4vw,18px);letter-spacing:-.02em;
  color:rgba(255,255,255,.82);line-height:1.3}
@media(max-width:820px){
  .ev{grid-template-columns:1fr;min-height:0}
  .ev > div{padding:24px}
  .ev > div + div::before{left:24px;right:24px;top:0;width:auto;height:1px;transform:none}
}
@media(max-width:640px){.ev-card{padding:28px 22px 18px}}

.ev-grid{display:grid;grid-template-columns:1fr 1fr;gap:56px;margin-top:0;
  text-align:left;align-items:start}
@media(max-width:860px){.ev-grid{grid-template-columns:1fr;gap:40px}}
.lab-s{font-size:12px;font-weight:800;letter-spacing:.08em;color:var(--muted);
  text-transform:uppercase;margin-bottom:18px}

/* 혼동행렬 */
.cmx{display:grid;grid-template-columns:auto repeat(3,1fr);gap:5px}
.cmx .hd{font-size:12px;font-weight:700;color:var(--muted);text-align:center;
  padding:6px 4px;align-self:center}
.cmx .hd.r{text-align:right;padding-right:12px}
.cmx .cl{padding:16px 8px;text-align:center;border-radius:9px;font-weight:800;
  font-size:16px;font-variant-numeric:tabular-nums;border:1px solid transparent}
.cmx .cl.d{background:color-mix(in srgb,var(--ok) calc(var(--i) * 0.5%), transparent);
  border-color:color-mix(in srgb,var(--ok) 35%, transparent);color:var(--fg)}
.cmx .cl.e{background:color-mix(in srgb,var(--bad) calc(var(--i) * 0.8% + 12%), transparent);
  color:var(--bad)}
.cmx .cl.z{color:var(--muted);opacity:.45;font-weight:600;
  background:color-mix(in srgb,var(--fg) 3%, transparent)}
.cmx-note{font-size:12.5px;color:var(--muted);margin-top:16px;line-height:1.75;
  max-width:44ch}

/* 등급별 재현율 */
.rc{display:grid;grid-template-columns:96px 1fr 62px 74px;gap:14px;align-items:center;
  padding:15px 0;border-bottom:1px solid var(--line)}
.rc:last-child{border-bottom:0}
.rc span{font-size:14px}
.rc i{display:block;height:8px;border-radius:100px;background:var(--ghost);overflow:hidden}
.rc i b{display:block;height:100%;background:var(--ok);border-radius:100px;
  transform-origin:left;transform:scaleX(0);
  transition:transform 1s cubic-bezier(.22,.61,.36,1)}
.in .rc i b{transform:scaleX(1)}
.rc:nth-child(3) i b{transition-delay:.1s}
.rc:nth-child(4) i b{transition-delay:.2s}
.rc em{font-style:normal;font-weight:800;font-size:15px;text-align:right}
.rc small{font-size:12px;color:var(--muted);text-align:right}
/* ★ 좁은 폭에서 수치를 라벨 옆에 붙여 둡니다 (2026-09-11).
   전에는 자동 배치라 DOM 순서(라벨 - 막대 - 수치 - 분수)대로 네 줄이 됐고,
   막대가 라벨과 수치 사이를 갈라놓았습니다. 재현율 블록이 487px 로
   혼동행렬(261px)의 두 배였습니다 — 데이터는 세 줄뿐인데. */
@media(max-width:520px){
  .rc{grid-template-columns:1fr auto;gap:8px}
  .rc span{grid-column:1;grid-row:1}
  .rc em{grid-column:2;grid-row:1;text-align:right}
  .rc i,.rc small{grid-column:1 / -1}
}


/* 혼동행렬 축 라벨 — 읽는 법을 문장 대신 라벨로 줍니다 (루닛 방식) */
.cmx-wrap{display:grid;grid-template-columns:auto 1fr;gap:10px;align-items:stretch}
/* 세로쓰기에서 한글은 눕지 않고 그대로 섭니다. 여기에 rotate(180deg) 를 걸면
   글자 하나하나가 거꾸로 뒤집힙니다. 세로로 위에서 아래로 읽게 둡니다. */
.cmx-y{writing-mode:vertical-rl;
  font-size:11px;font-weight:800;letter-spacing:.08em;color:var(--muted);
  text-transform:uppercase;text-align:center;padding-top:26px}
.cmx-x{display:block;font-size:11px;font-weight:800;letter-spacing:.08em;
  color:var(--muted);text-transform:uppercase;margin-bottom:8px;text-align:center}

/* ── 줄바꿈 ──────────────────────────────────────────────────
   balance : 제목의 줄 길이를 고르게 (2~4줄짜리 헤드라인용)
   pretty  : 마지막 줄에 한 단어만 남는 고아 줄을 막음 (본문용) */
.d1,.d2,h1,.auth-box h1,.drop h3,.hero-h1,.hero-lead{text-wrap:balance}
.lead,.body,.sec-sub,.fn,.cap,.cmx-note,.nouns,.st p,.tl-total,
.ev p,.desc,.auth-note{text-wrap:pretty}

/* ── 카운트업 자리 ────────────────────────────────────────────────
   숫자만 감싼 것이라 주변 글자 모양을 그대로 물려받아야 합니다.
   감싸는 순간 바깥 규칙(.stats span 같은 것)에 걸려 크기·색이 바뀝니다.
   파일 맨 뒤에 두는 것도 그래서입니다 — 같은 특정도면 뒤가 이깁니다. */
span.cu{font:inherit;color:inherit;letter-spacing:inherit}

/* ── 404 ──────────────────────────────────────────────────────── */
.nf{max-width:940px;margin:0 auto;padding:200px 32px 240px}
.nf-code{font-size:15px;font-weight:800;color:var(--accent);letter-spacing:.06em;
  margin-bottom:18px}
.nf h1{font-size:clamp(30px,4vw,42px);font-weight:800;letter-spacing:-.04em;
  line-height:1.25;margin-bottom:14px}
.nf-sub{font-size:16.5px;color:var(--muted);margin-bottom:36px}
.nf .btns{display:flex;align-items:center;gap:24px;flex-wrap:wrap}
@media(max-width:760px){.nf{padding:140px 22px 160px}}

/* ── 결과 화면 섹션 배치 ───────────────────────────────────────
   링크는 마크업상 카드 뒤에 둡니다. 한 열로 접히면 "자세히 보기"가
   보여줄 것보다 위에 오는데, 링크는 그 대상 다음에 와야 합니다.
   넓은 화면에서는 영역 이름으로 왼쪽 글 아래에 도로 붙입니다. */
.two.res-two{grid-template-areas:"say card" "cta card";grid-template-rows:auto 1fr;
  align-items:start;row-gap:0}   /* .two 의 gap 64px 이 행에도 걸려 글과 링크가 벌어집니다 */
.res-two .res-say{grid-area:say}
.res-two .res-cta{grid-area:cta;align-self:start;margin-top:22px}
.res-two .mini{grid-area:card;align-self:start}
@media(max-width:860px){
  .two.res-two{grid-template-columns:1fr;grid-template-areas:"say" "card" "cta";gap:26px}
  .res-two .res-cta{margin-top:0}
}

/* ── 검사 결과 — 판정 띠 ────────────────────────────────────────
   라벨을 위, 값을 아래로 세 칸이 같은 구조라 줄이 저절로 맞습니다.
   전에는 판정과 숫자가 서로 다른 기준선에 놓여 어수선했습니다. */
.vbar .res-id{margin-bottom:20px}
/* ★ 2026-09-17 — ~~`align-items:start`~~ 를 붙이면 칸이 **제 내용만큼만**
   높아집니다(판정 73 · 총 운동성 104.9 · 등급 분포 79.8 — 실측).
   구분선이 칸의 `border-left` 라 그 높이를 그대로 따라가, 막대 하나만
   **25px 짧게** 그려졌습니다(사용자 지적). 구분선은 덩어리를 가르는 것이지
   내용 길이를 재는 것이 아닙니다 — `stretch`(기본값)로 둡니다.
   `.vb-c` 가 flex column 이라 자식은 그대로 위에 붙고 선만 길어집니다 */
.vb-grid{display:grid;grid-template-columns:auto auto minmax(0,1fr)}
.vb-c{display:flex;flex-direction:column;gap:10px;min-width:0}
.vb-c + .vb-c{border-left:1px solid var(--line);margin-left:32px;padding-left:32px}
.vb-c .k{font-size:12px;font-weight:800;letter-spacing:.06em;color:var(--muted)}
.vb-c .n{font-size:12.5px;color:var(--muted)}
.vbar .verdict{font-size:42px;line-height:1;margin:0}
/* ★ 2026-09-17 — 판정 칸을 **글자 수에서 떼어 놓습니다.** `주의`(2자)와
   `교체 권장`(5자)의 폭 차가 68.8 <-> 145.2 라 뒤 칸이 통째로 밀렸습니다.
   가장 긴 판정을 높이 0 으로 깔아 **폭에만 기여**하게 합니다 —
   표의 `.tbl .sizer` 와 같은 수입니다(shell.css). 치수를 박지 않습니다 */
.vbar .verdict{display:flex;flex-direction:column}
.v-fit{display:block;height:0;overflow:hidden;visibility:hidden;font:inherit}
.vb-num{font-size:42px;font-weight:800;letter-spacing:-.04em;line-height:1}
.vb-num em{font-style:normal;font-size:17px;font-weight:700;color:var(--muted);margin-left:5px}
.vb-dist .bar{margin-top:5px}
.vb-dist .legend{margin:2px 0 0}
/* ★ 2026-09-17 — ~~`@900`~~ -> **`@800`**(정본 문턱). `.vbar`/`.vb-*` 는
   `app.js` 에서만 쓰는 **작업 영역** 규칙인데 랜딩 파일에 있어,
   2026-09-16 문턱 정리가 바로 아래 `.mtiles` 는 고치면서 여기를
   빼먹었습니다 — 선택자를 손으로 적어서 적은 것만 본 것입니다.
   ★ 800 으로 정한 근거 — 세 칸이 언제 무너지는지 재었습니다(실측):
       1010  분포칸 537.5 · 막대 504.5 · 범례 한 줄
        800  분포칸 343.5 · 막대 310.5 · 범례 한 줄   <- 여기까지 성립
        700  분포칸 243.5 · 막대 210.5 · 범례 **세 줄**
     `@900` 은 801~900 을 쓸데없이 한 열로 접고 있었습니다 */
@media(max-width:800px){
  .vb-grid{grid-template-columns:1fr;gap:22px}
  .vb-c + .vb-c{border-left:0;margin-left:0;padding-left:0;
    border-top:1px solid var(--line);padding-top:20px}
  .vbar .verdict,.vb-num{font-size:32px}
}

/* 지표 타일 — 여섯 값이 판독의 근거라 표 한 줄보다 크게 세웁니다 */
/* 타일 일곱 장을 4 + 3 으로 놓습니다. 남는 칸이 생기면 배경(선 색)이
   그대로 드러나서, 12칸 그리드에 span 을 나눠 딱 맞춥니다. */
.mtiles{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:1px;
  background:var(--line);border:1px solid var(--line);border-radius:16px;overflow:hidden}
.mt{background:var(--surface);padding:20px 22px 18px;display:flex;flex-direction:column;gap:10px;
  grid-column:span 3}
.mt:nth-last-child(-n+3){grid-column:span 4}
.mt .k{font-size:12.5px;color:var(--muted)}
.mt b{font-size:27px;font-weight:800;letter-spacing:-.035em;line-height:1}
.mt b em{font-style:normal;font-size:13px;font-weight:700;color:var(--muted);margin-left:4px}
.mt .n{font-size:11.5px;color:var(--muted)}
.mt .none{color:var(--muted);font-weight:600}
/* ★ 2026-09-16 — `.mtiles`/`.mt` 는 **작업 영역**(검사 결과 화면의 지표 타일)에도
   쓰입니다. 문턱을 작업 영역의 값으로 맞춥니다 — ~~760~~ -> **800**, ~~460~~ -> **640**.
   랜딩에는 이 두 클래스가 안 쓰이므로 랜딩 배치는 안 바뀝니다(실측 확인).
   작업 영역에서 화면이 바뀌는 폭을 **1120 · 1010 · 800 · 640 · 380** 으로 모으는
   정리의 일부입니다 */
@media(max-width:800px){
  .mtiles{grid-template-columns:repeat(6,minmax(0,1fr))}
  .mt,.mt:nth-last-child(-n+3){grid-column:span 3}
  .mt:last-child{grid-column:span 6}
}
@media(max-width:640px){
  .mtiles{grid-template-columns:1fr}
  .mt,.mt:nth-last-child(-n+3),.mt:last-child{grid-column:span 1}
}

/* 산점도 — 시료 평균 십자선. 지표의 VCL·LIN 이 구름의 어디인지 짚어 줍니다 */
.sc .mn{stroke:var(--fg);stroke-width:1;stroke-dasharray:3 4;opacity:.32}
.sc .mnl{fill:var(--muted);font-size:10px;font-weight:700}


/* ── 손이 올라가면 반응합니다 ─────────────────────────────────────────
   의미를 더하는 장치가 아니라 화면이 살아 있다는 표시입니다.
   움직임을 원하지 않는 환경에서는 색만 바뀝니다. */
.cmx .cl{cursor:default;transition:transform .18s ease, box-shadow .18s ease}
.cmx .cl:hover{transform:translateY(-3px) scale(1.04);position:relative;z-index:1;
  box-shadow:0 16px 26px -16px color-mix(in srgb,var(--fg) 62%, transparent)}
/* .ev 는 판 하나를 선으로 나눈 것이라(overflow:hidden) 띄우면 잘립니다 — 색으로만.
   ★ 시안에서 파란 띠가 되면서 흰 바닥으로 칠할 수 없게 됐습니다(09-10). 흰 물을 얹습니다 */
.ev > div{transition:background .2s ease}
.ev > div:hover{background:rgba(255,255,255,.08)}
/* ★ hover 는 시안대로 "채워지는" 것입니다. 예전의 들어올리기(translateY)는
   시안에 없어서 걷어냈습니다. 채움 자체는 위의 ::before 가 맡고,
   여기서는 글자색·테두리를 같은 길이(.28s)로 맞춰 함께 사라지게 합니다 */
.btn{transition:color .28s ease, box-shadow .28s ease}
.btn:hover{color:#fff;box-shadow:inset 0 0 0 1px transparent}
.play{transition:transform .18s ease, box-shadow .18s ease}
.play:hover{transform:translateY(-2px);
  box-shadow:0 12px 22px -14px color-mix(in srgb,var(--fg) 55%, transparent)}
/* ★ .cmp-card 는 .rev 이기도 합니다. transition 은 단축 속성이라 여기서 새로 쓰면
   .rev 의 opacity·transform 전환이 통째로 지워집니다 — 실제로 비교표 등장이
   죽었습니다(09-07). 그림자만 더하려면 .rev 의 값을 같이 적어 줘야 합니다. */
.cmp-card{transition:opacity .8s cubic-bezier(.22,.61,.36,1),
  transform .8s cubic-bezier(.22,.61,.36,1), box-shadow .3s ease}
/* ~~.cmp-card:hover 그림자~~ -> 2026-09-10 제거. 껍데기를 투명하게 바꾸면서
   그림자만 남아 표 뒤에 빈 네모가 떠 보였습니다(사용자 지적) */
@media(prefers-reduced-motion:reduce){
  .cmx .cl:hover,.btn:hover,.play:hover{transform:none}}
