/* ============================================================
   wonder micro pages — tokens.css (디자인 토큰 SOT)
   Phase 2b HTML-first · brief v2 §3 공통 시스템 준수
   - Paperlogy ONLY (Pretendard·시스템 폰트 = 즉시 반려)
   - 그라디언트 4색 = 정적 강조 4곳 한정 (배경 wash ❌)
   - warm_accent #F59E0B = CTA 단독 / trust_blue = 데이터·고지 존
   - 8px grid · word-break keep-all 전역
   ============================================================ */

/* ---- Paperlogy 로컬 @font-face (CDN ❌ · day lock)
   E5(#6): woff2 서브셋(KS X 1001 완성형 2350 + ASCII) 우선 · TTF 폴백 ·
   font-display: swap (block→swap: FOIT 제거, 폴백 즉시 렌더 후 스왑). 총량 438KB. ---- */
@font-face {
  font-family: "Paperlogy";
  src: url("fonts/Paperlogy-3Light.subset.woff2") format("woff2"),
       url("fonts/Paperlogy-3Light.ttf") format("truetype");
  font-weight: 300;
  font-display: swap;
}
@font-face {
  font-family: "Paperlogy";
  src: url("fonts/Paperlogy-4Regular.subset.woff2") format("woff2"),
       url("fonts/Paperlogy-4Regular.ttf") format("truetype");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Paperlogy";
  src: url("fonts/Paperlogy-7Bold.subset.woff2") format("woff2"),
       url("fonts/Paperlogy-7Bold.ttf") format("truetype");
  font-weight: 700;
  font-display: swap;
}
@font-face {
  font-family: "Paperlogy";
  src: url("fonts/Paperlogy-9Black.subset.woff2") format("woff2"),
       url("fonts/Paperlogy-9Black.ttf") format("truetype");
  font-weight: 900;
  font-display: swap;
}

/* ---- Pretendard 로컬 @font-face (E7 · 폰트 하이브리드 · day lock 2026-07-08)
   ★ 마이크로사이트(web) 한정 하이브리드 예외: 헤드=Paperlogy(브랜드 시그니처)·본문/UI=Pretendard.
   DA/PPT/영상은 Paperlogy-only 유지 (design-language § 1 주석 참조).
   KS X 1001(2350)+ASCII 서브셋 woff2, CDN ❌ 로컬만. 3 weight(400/600/700) 총 537KB. ---- */
@font-face {
  font-family: "Pretendard";
  src: url("fonts/Pretendard-400.subset.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Pretendard";
  src: url("fonts/Pretendard-600.subset.woff2") format("woff2");
  font-weight: 600;
  font-display: swap;
}
@font-face {
  font-family: "Pretendard";
  src: url("fonts/Pretendard-700.subset.woff2") format("woff2");
  font-weight: 700;
  font-display: swap;
}

:root {
  /* ---- 폰트 토큰 (E7 하이브리드) ----
     --font-head = Paperlogy (헤드라인·대형 타이틀 — 브랜드 시그니처, 웹 스케일로 축소 운용)
     --font-body = Pretendard (본문·서브·UI·칩·버튼·스탯·고객보이스·푸터 — 웹 제품 가독) */
  --font-head: "Paperlogy", "Pretendard", sans-serif;
  --font-body: "Pretendard", "Paperlogy", sans-serif;

  /* ---- wonder 그라디언트 4색 (정적 강조 전용) ---- */
  --w-g1: #4ae68a;
  --w-g2: #3ec8e8;
  --w-g3: #7b5cf5;
  --w-g4: #d94ee8;
  /* 텍스트 wrap용 — 밝은 배경 위 가독을 위해 mint 구간을 짧게 편향
     r2: 첫 스톱 #1fc776 (딥 민트 — 흰 배경 대비 3:1+ 목표, 레드팀 P1 #4) */
  --w-grad: linear-gradient(102deg, #1fc776 0%, var(--w-g2) 20%, var(--w-g3) 58%, var(--w-g4) 100%);
  --w-grad-bar: linear-gradient(90deg, var(--w-g1), var(--w-g2), var(--w-g3), var(--w-g4));

  /* ---- 기능 색 ---- */
  --accent: #f59e0b;            /* warm_accent — CTA 단독 */
  --accent-deep: #de8a05;
  --on-accent: #2b1d02;         /* 앰버 위 잉크 (대비 확보) */
  --trust-blue: #1e40af;        /* 데이터·고지 존 */
  --trust-ink: #0e1633;         /* trust 심연 서피스 (S3 데이터 존) */
  --trust-soft: #e9eefb;

  /* ---- 뉴트럴 (순수 #000 금지) ---- */
  /* ★ 2026-07-16 접근성(KWCAG 2.1 · 명암비 4.5:1) 상향:
     --ink-4 구 #8a90a2 = 흰 배경 3.19:1 / paper-2 2.97:1 / gray-100 2.87:1 → 전부 미달.
     고지(예상·개인차·조건·예시)가 그것이 수식하는 주장보다 흐리게 읽히는 구조 = 다크패턴.
     #50566a = 흰 5.18:1 / paper-2 4.84:1 / gray-100 4.66:1 → 사용 중인 모든 서피스에서 4.5:1+ 충족.
     (--ink-4 는 v3 전 구간 라이트 배경에서만 사용 — 다크존 사용 0건 확인 후 토큰 일괄 상향) */
  --ink: #101425;
  --ink-2: #3d4356;
  --ink-3: #464c5e;
  --ink-4: #50566a;
  --paper: #ffffff;
  --paper-2: #f6f7fa;
  --gray-100: #f1f3f7;
  --hairline: rgba(16, 20, 37, 0.08);
  --hairline-strong: rgba(16, 20, 37, 0.14);

  /* ---- 8px grid spacing ----
     ★ 2026-07-16 R2: 마이크로 티어 3개 추가(--s-half/--s1half/--s2half).
     왜 필요한가: 스케일은 이미 있었는데 **안 쓰였다**(실측 채택률 6.2% · 간격 65~68종 난립).
     원인의 절반은 8·16·24 사이가 비어 있었다는 것 — 12px·20px 를 표현할 토큰이 없으니
     손으로 11/12/13/14 를 쳤고, 한 번 손으로 치기 시작하면 53·88 같은 값도 같이 들어온다.
     빈칸을 메워 "토큰으로 표현 가능한 값"의 커버리지를 먼저 확보한다.
     흡수 매핑: 1~6→4 · 7~10→8 · 11~14→12(최다 이탈 14px) · 15~18→16 · 20~22→20 · 24·26→24 · 30~34→32 */
  --s-half: 4px;
  --s1: 8px;  --s1half: 12px; --s2: 16px; --s2half: 20px;
  --s3: 24px; --s4: 32px;
  --s5: 40px; --s6: 48px; --s7: 56px; --s8: 64px;
  --s10: 80px; --s12: 96px; --s16: 128px;

  /* ---- ★ 2026-07-16 R2 fluid 간격 토큰 (v2 clamp 29종 → 5종)
     왜 필요한가: v2 는 같은 22px 에서 출발하는 clamp 변종이 4개 있었다
     (clamp(14px,2vw,22px) / clamp(18px,3vw,22px) / …). 서로 다른 성장률을 손으로 정한 값들이라
     뷰포트를 넓히면 간격끼리 서로 추월한다 = 리듬이 폭마다 재배열된다.
     성장 곡선을 5개로 고정하고 전부 여기서만 정의한다. */
  --f-1: clamp(14px, 2vw, 20px);   /* 조밀 — 카드 내부 요소 사이 */
  --f-2: clamp(20px, 3vw, 32px);   /* 기본 — 블록 사이 */
  --f-3: clamp(26px, 4vw, 44px);   /* 넉넉 — 헤드 → 콘텐츠 */
  --f-4: clamp(36px, 5vw, 56px);   /* 큰 — 섹션 내 큰 덩어리 사이 */
  --f-5: clamp(48px, 7vw, 72px);   /* 최대 — 섹션 내 최상위 분절 */

  /* ---- ★ 2026-07-16 R2 섹션 세로 리듬 (v2 4티어 난립 → v3 의 단일 리듬으로 통일)
     v3 는 이미 128 단일이었고 그게 이 페이지의 가장 좋은 자산 중 하나다. v2 를 여기 맞춘다.
     --sec-y-em = 강조 섹션 1티어만 허용(v3 hero 선례). 그 외 티어 신설 ❌. */
  /* ★ clamp 이 아니라 **브레이크포인트 계단**인 이유 (1차 구현에서 실측으로 잡은 내 실수):
     처음엔 `clamp(96px, 8vw, 128px)` 로 썼더니 **1440 에서 8vw = 115px** 이 나왔다.
     v3 는 원래 1024↑ 에서 128 고정이었으므로 이건 v3 를 128 → 115 로 **깎는 회귀**다
     (진단서가 "건드리지 말고 이식 원본으로 쓰라"고 못 박은 자산을 조용히 내리는 셈).
     리듬은 뷰포트에 비례해 흘러야 하는 값이 아니라 **지면 크기별로 정해지는 값**이다.
     계단: 96(모바일) → 128(1024↑ · v3 원본 그대로) → 160(1728↑ · 세로 레인) */
  --sec-y: 96px;
  --sec-y-em: 96px;
  --sec-y-strip: clamp(32px, 5vw, 44px);   /* 반론 스트립 = 섹션이 아니라 띠 */

  /* ---- ★ 2026-07-16 컨테이너 스케일 토큰 (v2·v3 공용 어휘 · 「2안 = v3 표준 승격」)
     왜 필요한가: v2 는 1120/920/880/760/680 5종을 하드코딩해 무체계였고,
     v2 `.wrap`(1120) 과 v3 `.wrap`(720) 이 **같은 클래스명 다른 값** = 두 페이지를
     오갈 때 같은 이름이 다른 폭을 뜻하는 함정이었다. 이름을 폭에 맞춰 분리한다.
       .wrap-sm = --w-narrow (읽기 칼럼 · 구 v3 .wrap)
       .wrap-lg = --w-wide   (본문 와이드 · 구 v2 .wrap)
     --w-wide 는 1440↑ 에서 확장된다(아래 데스크톱 스케일 레인). ---- */
  --w-read: 680px;              /* 집중 읽기 (단일 카드) */
  --w-narrow: 720px;            /* 카피 칼럼 (구 v3 .wrap) */
  --w-mid: 920px;               /* 2컬럼 카드 그리드 */
  --w-wide: 1100px;             /* 본문 와이드 (구 v2 .wrap · 1440↑ 확장) */
  --pad-x: 20px;

  /* ---- ★ 2026-07-16 포커스 링 (KWCAG 2.4.7 · v2·v3 공용 토큰 1개)
     왜 필요한가: 키보드 사용자는 지금 자기가 어디에 있는지 볼 방법이 없었다.
     v2 `:focus` 2건(input border-color만)·CTA 9개/링크/FAQ 전무, v3 도 input 1건뿐.
     ★ box-shadow 가 아니라 **outline** 인 이유 (1차 구현 실패에서 배움):
       처음엔 `box-shadow: 0 0 0 3px …` 로 만들었더니 **히어로 CTA 에만 링이 안 떴다**.
       `.btn-amber`/`.btn-cta` 가 자기 box-shadow(앰버 글로우)를 갖고 있고 특이도가
       (0,1,0) 로 `:where(...):focus-visible` 과 동률 → 나중에 선언된 버튼 규칙이 이김.
       = 페이지에서 가장 중요한 버튼만 조용히 접근성 미달. outline 은 box-shadow 와
       다른 속성이라 애초에 충돌하지 않고, 요소의 border-radius 도 따라간다. ---- */
  --focus-ring: 3px solid var(--ink);
  --focus-ring-dark: 3px solid var(--paper);

  /* ---- Type scale (360px 기준 · brief §3-A 4단 위계) ----
     ══ ★★ 2026-08-07 (day "텍스트들이 전반적으로 더 크게!") 스케일 전체 상향 ══════════════
     🔴 **개별 셀렉터를 손으로 만지지 않았다.** 여기(토큰) 하나만 올리면 이걸 쓰는 곳이 전부
        같이 올라가고 **위계 비율이 그대로 유지된다.** 개별 값을 고치면 위계가 깨지고
        다음 사람이 무엇이 기준인지 못 찾는다.

     ── 무엇을 얼마나 (근거) ─────────────────────────────────────
     · **본문 15.5 → 17px (+9.7%)** = 기준선. 모바일 접근성 하한 16px 을 **넘긴다**
       (구 15.5px 은 하한 미달이었다). 나머지는 이 기준에 맞춰 비율을 지켰다.
     · **서브 19 → 20.5px (+7.9%)** = 본문 대비 1.2배 유지
     · **h2 25 → 27px (+8%)** · vw 계수도 같이(7.2 → 7.6vw)
     · **고지 12 → 13px · 법정 11 → 12px** — ★ 다른 글자가 커지면 고지는 **상대적으로 더
       작아 보인다.** 안 읽히는 고지는 고지가 아니라서 같이 올렸다(법정 하한 11px 은 지킨다).
     · 🔴 **display(히어로 h1)는 37 → 38px (+2.7%) 만.** 이미 크기 때문에 같은 비율로 올리면
       **히어로만 화면을 잡아먹고** 첫 화면에서 CTA 가 밀려난다(8/7 `/job/` 3줄 사고와 같은 계열).
       상한도 46 → 47px 로만. **전부 같은 비율로 올리는 게 아니라 위계를 좁히는 방향**이다. */
  --fs-display: clamp(38px, 11.5vw, 47px);  /* Hook 히어로 — 9Black (증가폭 최소) */
  --fs-h2: clamp(27px, 7.6vw, 32px);        /* 섹션 헤더 — 9Black */
  --fs-sub: 20.5px;                          /* 서브·칩·스텝 — 700 */
  --fs-body: 17px;                           /* 본문 — 400 (★ 모바일 하한 16px 상회) */
  /* ★ 2026-07-16 R2: 구 주석은 "300" 이었으나 Pretendard 는 300 face 를 로드하지 않는다
     → 실제 렌더는 400 이었다(실측: 잉크 폭 완전 동일 = _internal/ghost_weight_probe.py).
     주석·선언을 실제 렌더값으로 정정. 시각 변화 0, 유령 선언만 제거. */
  --fs-cap: 13px;                            /* 각주·고지 — 400 (12→13 · 위 주석 참조) */
  --fs-legal: 12px;                          /* 푸터 법정 — 400 (11→12 · 하한 11px 은 유지) */

  /* ═══ ★ 2026-07-16 R2 · elevation 6종 (그림자를 "높이"로 만든다) ═══
     왜 필요한가: hover 규칙 22개 중 box-shadow 를 건드리는 게 **0건**이었다.
     요소가 뜨는데(translateY) 그림자는 그대로 = 물리 법칙 위반이고, 그게 "싼 느낌"의 정체다.
     더 나쁜 건 v3 `.btn-cta`·`.wtd-step` 이 transition 에 `box-shadow` 를 **선언만 하고**
     대응 hover 값이 없어 발화 불가였다는 것 — 하려다 만 흔적이 코드에 남아 있었다.
     그래서 "그림자 값"이 아니라 **높이 단계**를 토큰화한다. hover = 한 단계 위로.
     · 2겹 구조(close/ambient) = 접촉 그림자 + 확산 그림자. 1겹 큰 blur 는 글로우지 그림자가 아니다.
     · 중립색은 --ink(#101425) 1종으로 고정 — 아래 「그림자 중립색」 주석 참조. */
  --e1: 0 1px 2px -1px rgba(16, 20, 37, 0.06), 0 2px 6px -2px rgba(16, 20, 37, 0.05);
  --e2: 0 2px 4px -2px rgba(16, 20, 37, 0.06), 0 8px 20px -6px rgba(16, 20, 37, 0.08);
  --e3: 0 4px 8px -3px rgba(16, 20, 37, 0.07), 0 16px 36px -10px rgba(16, 20, 37, 0.10);
  --e4: 0 8px 16px -6px rgba(16, 20, 37, 0.08), 0 32px 64px -20px rgba(16, 20, 37, 0.14);
  /* 앰버 CTA — ★크기 무관 단일. inset 하이라이트 = 상단 광원(v3 --sh-amber 의 정답을 승계). */
  --e-amber:   0 2px 6px -2px rgba(222, 138, 5, 0.30), 0 12px 28px -10px rgba(222, 138, 5, 0.38), inset 0 1px 0 rgba(255, 255, 255, 0.35);
  --e-amber-h: 0 4px 10px -3px rgba(222, 138, 5, 0.34), 0 18px 40px -12px rgba(222, 138, 5, 0.44), inset 0 1px 0 rgba(255, 255, 255, 0.35);

  /* ---- 그림자 · 베젤 (하드웨어 감각)
     ★ 그림자 중립색 = rgba(16,20,37) = --ink **1종만**. (2026-07-16 R2)
     구: rgba(16,20,37) 31회 / rgba(15,18,24) 2회 / rgba(14,22,51) 1회 / rgba(0,0,0) 2회 = 4종.
     육안으로 구분되지 않는 차이가 4종 = 값을 손으로 쳤다는 증거이고, rgba(0,0,0) 은
     design-language 「순수 #000 금지」 정면 위반이었다. 신규 그림자는 반드시 --e1~--e4 사용. */
  --sh-float: 0 36px 72px -30px rgba(16, 20, 37, 0.22), 0 8px 22px -10px rgba(16, 20, 37, 0.10);
  --sh-card: 0 24px 60px -18px rgba(16, 20, 37, 0.10), 0 2px 8px -2px rgba(16, 20, 37, 0.05);
  --sh-amber: var(--e-amber);   /* ← 별칭 (구 이름 호출부 보존 · 실체는 elevation 토큰) */
  --bezel-tray: rgba(16, 20, 37, 0.045);
  --bezel-ring: rgba(16, 20, 37, 0.07);
  --bezel-inset: inset 0 1px 1px rgba(255, 255, 255, 0.65);

  /* ---- 라운드 ---- */
  --r-xl: 28px; --r-lg: 20px; --r-md: 14px; --r-sm: 10px; --r-pill: 999px;

  /* ═══ 모션 (Supanova signature — linear·ease-in-out 금지) ═══
     ★ 2026-07-16 R2 재편. 구: 이 페이지 이징의 90~96%를 easeOutExpo 하나가 독점했다.
     그건 일관성이 아니라 **모노톤**이다. easeOutExpo 는 변화의 80%를 첫 90ms 에 끝내는
     극단 곡선이라, 0.3s hover 에 걸면 남은 210ms 는 눈에 안 보이는 잔여를 기어간다
     (= 반응이 굼뜨게 느껴지는 실제 원인). 히어로급 등장에만 쓰고 나머지는 용도별로 나눈다.
     duration 도 마찬가지 — 0.4s 와 0.45s 를 인간은 구분하지 못한다. 6단으로 고정. */
  --ease-standard: cubic-bezier(0.2, 0, 0, 1);        /* hover·색·보더 — 기본값 */
  --ease-decel:    cubic-bezier(0.05, 0.7, 0.1, 1);   /* 진입: 리빌·결과·모달 */
  --ease-accel:    cubic-bezier(0.3, 0, 0.8, 0.15);   /* 퇴장 */
  --ease-emphasis: cubic-bezier(0.16, 1, 0.3, 1);     /* ★히어로급 1~2곳만 (구 --ease) */
  --ease-spring:   cubic-bezier(0.34, 1.56, 0.64, 1); /* 토글·성공 = 오버슈트 */
  --ease-loop:     cubic-bezier(0.4, 0, 0.6, 1);      /* 무한 루프 (ease-in-out hard ban 치환) */
  --ease: var(--ease-emphasis);   /* ← 별칭 (구 이름 호출부 보존) */

  --dur-1: 120ms;  /* 아이콘·체크 = 작은 요소는 빨라야 한다 */
  --dur-2: 180ms;
  --dur-3: 260ms;  /* 색·보더·페이드 */
  --dur-4: 400ms;  /* 리빌·아코디언 = 형태 변화 */
  --dur-5: 560ms;  /* 모달 등장 */
  --dur-6: 900ms;  /* 값 표현 전용 (게이지·카운트업) */
}

/* ★ 2026-07-16 데스크톱 스케일 레인 (P0-1 · day "PPT 같다"의 근본 원인)
   왜 필요한가: 컨테이너가 1100 에 고정돼 있어 1440 에서도 1920 에서도 콘텐츠가
   같은 폭이었다. 1920 기준 좌우 각 410px = 화면의 43%가 빈 여백 → 슬라이드를
   가운데 띄운 "PPT 느낌"의 정체. day 검수 환경 = PC 와이드 모니터
   (feedback_responsive_desktop_layout_mandatory). 광고 랜딩 단일 코드 유지. */
/* ※ 컨테이너 토큰의 브레이크포인트는 전부 여기(SOT)에 모은다 —
   shell.css·페이지 CSS 에서 :root 를 다시 선언하면 나중 파일이 이겨서 레인이 조용히 죽는다. */
@media (min-width: 768px)  { :root { --pad-x: 32px; } }
/* ★ 1024↑ = v3 가 원래 갖고 있던 리듬(128 단일). v2 를 여기 맞춘다(구 v2 = 88/96/104/120 4티어). */
@media (min-width: 1024px) { :root { --sec-y: 128px; --sec-y-em: 164px; } }
@media (min-width: 1440px) { :root { --w-wide: 1280px; --pad-x: 40px; } }
@media (min-width: 1728px) { :root { --w-wide: 1400px; --pad-x: 48px; } }

/* ★ 2026-07-16 R2 · 세로 레인 (1920 에서 "PPT 같다"가 남아 있던 물리적 이유)
   직전 라운드에서 가로 레인(--w-wide 1100→1400)만 열고 세로는 128 고정으로 뒀다.
   그래서 1440→1920 사이에 비율이 **반전**했다:
     가로 여백은 2.6~3.3배로 벌어지는데(v3 120→308px) 세로 패딩은 그대로 128 →
     세로/가로 비 1.07 → 0.42. 즉 화면이 넓어질수록 **세로가 가로보다 2.4배 답답**해진다.
   여백이 사방으로 같이 자라야 콘텐츠가 "지면 위에 놓인 것"으로 읽힌다. 목표 비 0.57~0.62.
   ※ wrap-sm(읽기 칼럼) 섹션은 폭이 720 고정이라 가로 여백이 600px 까지 벌어진다 —
     세로를 176 까지 올려도 비 0.29 가 한계다(패딩으로 메울 수 있는 문제가 아니다).
     그 섹션들의 진짜 해법은 레이아웃(리본 폭·2단 구성)이라 별도 판단 → Lead 추가 의뢰. */
/* ※ 기본값을 @media **앞**에 둔다. 뒤에 두면 같은 특이도(0,1,0)라 미디어 매칭과 무관하게
   나중 선언이 이겨서 1728 레인이 조용히 죽는다(이 파일이 컨테이너 토큰에서 겪은 그 함정). */
:root { --sec-y-narrow: var(--sec-y); }   /* 1728 미만 = 본 리듬과 동일 */
@media (min-width: 1728px) {
  :root {
    --sec-y: 160px;
    --sec-y-em: 200px;        /* 강조 티어 비(1.28) 유지 — 160 과 붙으면 티어가 죽는다 */
    --sec-y-narrow: 176px;    /* wrap-sm 섹션 (persona·faq·app-outlink) */
  }
}

/* ---- ★ 포커스 링 전역 (KWCAG 2.4.7 · :focus-visible 기준) ----
   마우스 클릭엔 안 뜨고 키보드 탐색에만 뜬다(설계 의도).
   outline-offset 로 요소 바깥에 띄워 앰버·다크·화이트 어떤 배경에서도 대비를 얻는다. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: var(--focus-ring);      /* outline 은 요소 자신의 border-radius 를 따라간다 */
  outline-offset: 3px;
}
/* 다크 서피스 위 요소는 반전 링 */
:where(.sec-final, .footer, .myth, .final, .review-card--dark)
  :where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: var(--focus-ring-dark);
}

/* ═══ ★ 2026-07-16 R2 · prefers-reduced-motion 전역 (접근성 · WCAG 2.3.3) ═══
   왜 필요한가: 두 페이지 모두 reduced-motion 을 **선언은 했는데 실효가 없었다**.
     · v2 `@media(reduced){ *{animation:none!important} }` → animation 만 막고
       **transition 63개는 그대로 살아 있었다**.
     · v3 는 `.wt-hint svg` 의 `swipe-nudge 2.4s infinite` 를 개별 규칙으로 껐지만,
       개별 대응은 새 모션이 추가될 때마다 누락된다(그리고 실제로 누락돼 있었다).
   전정기관 장애가 있는 사용자에게 무한 루프 모션은 불편이 아니라 **증상 유발**이다.
   그래서 개별 대응이 아니라 전역 차단을 깐다 — 이후 추가되는 모션도 자동으로 덮인다.
   · 0 이 아니라 0.01ms 인 이유: duration 0 은 transitionend/animationend 가 안 나가
     그 이벤트에 의존하는 스크립트가 멈춘다. 사실상 즉시이면서 이벤트는 살린다.
   · 개별 페이지의 reduced-motion 블록은 그대로 둔다(중복이지 충돌이 아니다 —
     transition:none 이든 duration:.01ms 든 결과는 "즉시"로 같다). */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---- 전역 리셋 ---- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  font-family: var(--font-body);   /* Pretendard — 본문·UI 웹 제품 가독 (E7 하이브리드) */
  font-weight: 400;
  font-size: var(--fs-body);
  line-height: 1.65;
  color: var(--ink);
  background: var(--paper);
  word-break: keep-all;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
/* ---- 헤드라인·대형 타이틀 = Paperlogy(브랜드 시그니처) · 웹 스케일 (E7) ----
   본문/서브/칩/버튼/스탯/고객보이스/푸터은 body 상속(Pretendard). */
h1, h2, h3, .h2, .display, .wordmark, .e-hook, .s3-copy,
.hero-e h1 { font-family: var(--font-head); }
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
figure { margin: 0; }

/* ═══ 그라디언트 텍스트 (구 단위 매끈 — 글자별 갈라짐 ❌) ═══
   ★★ 2026-07-16 R2 · background-clip:text 룰 lock (같은 버그 3번째 재발 방지) ★★

   근본 원인 (매번 "그 요소만" 고치고 룰로 못 박지 않아 재발했다):
     background-clip:text 는 **배경 박스를 글자 모양으로 오려내는** 것이지, 배경 박스를
     글자 크기로 만들어주지 않는다. 그래서 요소가 글자보다 넓으면(= display:block 이거나
     flex/grid item 이라 blockify 되면) 그라디언트는 **컨테이너 폭** 위에 그려지고,
     글자는 그중 자기가 깔고 앉은 구간만 샘플링한다.
     → 잉크가 박스의 일부만 덮으면 **마지막 스톱이 빈 공간에 떨어져 그 색이 화면에서 사라진다.**

   실측된 재발 이력 (전수 점검 = _internal/token_audit.py 가 모든 clip:text 요소의 잉크 피복률을 잰다):
     · v2 `.review__count` 「6,300」 — 이전 라운드에서 inline-block 으로 이미 수정 (현 100%)
     · v2 `.quote-mark` ×3      — 잉크 **7.7%** → 3건 전부 단색 렌더(2번째 스톱 미도달)
     · v3 `.hv-score .fee b` 「약 69만원」 — 잉크 **56.3%** → 마젠타 #d94ee8 실종 (라이브)

   ▶ 법칙: background-clip:text 를 쓰는 요소는 **페인트 박스가 글자에 밀착**해야 한다.
       · inline  → 이미 shrink-wrap 됨. 추가 조치 불필요 (실측 100%).
       · block / flex·grid item → `width: fit-content` **의무**.
   ▶ 아래 가드는 blockify 되는 케이스를 자동으로 덮는다. 신규 요소도 여기 걸린다.
     (display 는 건드리지 않는다 — inline↔inline-block 전환은 baseline·line-box 를 흔들어
      멀쩡한 줄바꿈을 깨뜨린다. 필요한 건 "폭"이지 "display" 가 아니다.) */
.grad-text {
  background: var(--w-grad);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}
/* ★ 가드 — clip:text 요소가 블록 흐름에 놓이면 폭을 글자에 밀착시킨다.
   inline 요소에는 width 가 애초에 적용되지 않으므로 이 규칙은 그들에게 무해(no-op)하다. */
.grad-text, .grad-full, .quote-mark, .receipt__total, .review__count, .hv-score .fee b {
  width: fit-content;
}
/* 가운데 정렬 문맥에서 fit-content 는 좌측으로 붙는다 → 정렬 유지용 보정 */
.center > .grad-text, .center .review__count { margin-inline: auto; }

/* ═══ ★ 2026-07-16 R2 · 수치 표시 = tabular-nums (실측 v2 0/25 · v3 0/32) ═══
   왜 필요한가 (frontend-design.md 「수치 표시 무조건 tabular-nums」):
     ① 비례숫자는 글립마다 폭이 다르다(1 은 좁고 0·8 은 넓다). v2 영수증은 금액 3줄이
        **우측 정렬인데도 자릿수가 세로로 안 맞았다** — 「약 104만원 / 약 69만원 / 약 173만원」이
        영수증 문법을 흉내내면서 정작 영수증의 핵심(자리 맞춤)을 못 지킨 상태.
     ② 카운트업 중 숫자가 바뀔 때마다 폭이 진동한다(실측 ±0.41px) → 옆 요소가 미세하게 떨린다.
   두 문제 모두 이 한 줄로 동시에 해결된다. 표시용 수치에만 건다(본문 텍스트 ❌). */
.receipt__amt, .receipt__total, .review__count, .hero__stat-value,
.calc__amt, .calc__total, .statstrip__item b,
.ev-num, .ev-unit, .hv-score .tt b, .ff-donut .ctr b, .wts-feebar .seg,
.s7flip-bar .seg-a, .s7flip-piece .face,
input[inputmode="numeric"] {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;   /* 폰트가 numeric-spacing 을 노출 안 할 때의 폴백 */
}
