@charset "UTF-8";
/* =============================================================================
   k-saju-astrology — style.css
   -----------------------------------------------------------------------------
   이 파일이 스타일 원본(single source)입니다.
   design/index.html · design/result-sample.html 의 인라인 <style> 은
   이 파일을 기계적으로 복사한 사본이며, app/ 구현본은 그 사본이 아니라
   이 파일을 복사해 씁니다.

       design/style.css  ──(복사)──▶  design/*.html 의 인라인 <style>
       design/style.css  ──(복사)──▶  app/assets/css/style.css

   방향은 단방향입니다. 사본을 고치지 말고 이 파일을 고치십시오.
   자세한 내용은 design/design-guide.md §0 을 보십시오.

   외부 리소스 0건: 웹폰트·CDN·이미지 URL·아이콘 라이브러리를 쓰지 않습니다.
   ========================================================================== */

/* =============================================================================
   1. 토큰
   ========================================================================== */
:root{
  /* 🔴 v1.1 (P2-1): 이 문서가 두 가지 색 구성을 지원한다고 UA 에 알립니다.
     이 한 줄이 없으면 §15 의 다크 토큰이 다 적용돼도 **폼 컨트롤·스크롤바·
     체크박스만 라이트로 남아** 화면이 어긋납니다. 브라우저가 그리는 부분은
     CSS 토큰이 닿지 않고 이 속성만 봅니다.
     ⚠ 순서가 의미를 갖습니다. `light` 가 앞이므로 OS 가 라이트이거나 선호를
       밝히지 않으면 지금까지와 완전히 같은 화면입니다.
     ⚠ 토글 UI 는 만들지 않습니다. OS 선호만 따릅니다 — 이 사이트는 이용자
       설정을 저장하지 않습니다(대표 결정-2). */
  color-scheme:light dark;

  /* --- 색: 기본 --- */
  --c-primary:#1F3A6E;
  --c-primary-dark:#152847;
  --c-primary-tint:#E9EEF7;
  --c-text:#16181D;
  --c-text-sub:#565E6B;
  --c-text-invert:#FFFFFF;
  --c-bg:#FFFFFF;
  --c-bg-soft:#F4F6F9;
  --c-border:#D7DDE6;
  --c-border-strong:#7F8A99;  /* 3.50:1 vs #FFF · 3.23:1 vs #F4F6F9 — 대표 결정-13. 구 #B4BDCA 는 1.90:1 미달 */

  /* --- 색: 오행(五行). 면/틴트/틴트 위 텍스트 3종을 항상 함께 씁니다 --- */
  --c-wood:#2F7A4F;  --c-wood-tint:#E8F3EC;  --c-wood-text:#1F5637;
  --c-fire:#B23A2E;  --c-fire-tint:#FBECEA;  --c-fire-text:#8C2A21;
  --c-earth:#9A6B12; --c-earth-tint:#FAF1DF; --c-earth-text:#73500D;
  --c-metal:#6E7783; --c-metal-tint:#F0F2F5; --c-metal-text:#4E5661;
  --c-water:#2A5C8A; --c-water-tint:#E7F0F7; --c-water-text:#1D4265;

  /* --- 색: 시맨틱 --- */
  --c-notice:#8A5A12; --c-notice-tint:#FBF3E3; --c-notice-text:#6E4710;
  --c-error:#B3261E;  --c-error-tint:#FBEAE8;  --c-error-text:#8E1D17;

  /* --- 색: TODO 표시(배포 전 반드시 0개가 되어야 하는 것) --- */
  --c-todo-tint:#FFF4CC; --c-todo-border:#B98A05; --c-todo-text:#63480A;

  /* --- 색·치수: 광고 ---
     🔴 v1.1 (P2-1): 아래 4개는 **§15 다크 블록에서 절대 덮어쓰지 않는 토큰**입니다.
     AD-L15(라벨 색·크기·굵기 무변경) · AD-L19(슬롯 패널은 흰 불투명) 는 측정값이
     곧 규칙인 자리이고, 색 구성이 바뀐다고 그 값이 바뀌면 안 됩니다.
     그래서 다크에서 값이 뒤집히는 --c-text-sub 에 라벨을 매달아 두지 않고
     --c-ad-label 로 떼어 냈습니다. **라이트에서는 두 값이 같으므로 화면은 그대로입니다**
     (#565E6B = 구 --c-text-sub 값). 다크에서는 §15 가 흰 패널을 깔아 라벨이
     계속 흰 면 위에 있게 합니다 — 색을 바꾸는 대신 면을 지키는 쪽입니다.
     check-l0-contrast.js 의 위생 검사가 이 4개의 다크 재선언을 FAIL 시킵니다. */
  --c-ad-panel:#FFFFFF;       /* 슬롯 래퍼 패널 면 — AD-L19. 다크에서도 흰색 */
  --c-ad-label:#565E6B;       /* 라벨 글자색 — AD-L15. 흰 패널 위 6.54:1 고정 */
  --c-ad-surface:#F1F3F6;
  --c-ad-border:#7F8A99;      /* 3.50:1 vs #FFF · 3.15:1 vs 슬롯 면 — 대표 결정-13. 구 #DCE1E8 은 1.31:1 미달 */
  --ad-h-inline:280px;   /* 인라인 슬롯 예약 높이 */
  --ad-h-side:600px;     /* 사이드바 슬롯 예약 높이 */
  --ad-gap:32px;         /* 슬롯 래퍼 상하 이격 */
  --ad-gap-afterresult:48px; /* 결과 카드 → 슬롯 추가 이격 */

  /* --- 폰트 --- */
  --font-en:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  --font-ja:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,
            "Hiragino Kaku Gothic ProN","Hiragino Sans",
            "Yu Gothic Medium","Yu Gothic",YuGothic,Meiryo,
            "Noto Sans JP","Noto Sans CJK JP","MS PGothic",sans-serif;
  --font-han:"Hiragino Mincho ProN","Yu Mincho",YuMincho,"MS Mincho",
             "Noto Serif JP","Noto Serif KR","Batang",serif;
  --font-mono:ui-monospace,SFMono-Regular,Menlo,Consolas,"Courier New",monospace;

  /* --- 타입 스케일 --- */
  --fs-h1:28px; --fs-h2:21px; --fs-h3:17px;
  --fs-body:16px; --fs-sm:14px; --fs-caption:13px;
  --fs-glyph:34px;
  --lh-en:1.65; --lh-ja:1.85;
  --measure-en:66ch;  /* 영문 본문 최대 폭 */
  --measure-ja:40em;  /* 일본어 본문 최대 폭(전각 40자 상당) */

  /* --- 간격(4px 배수) --- */
  --sp-1:4px;  --sp-2:8px;  --sp-3:12px; --sp-4:16px; --sp-5:20px;
  --sp-6:24px; --sp-8:32px; --sp-10:40px; --sp-12:48px; --sp-16:64px;

  /* --- 레이아웃 --- */
  --maxw:1120px;
  --tap:44px;
  /* 🔴 v1.1 (P2-3): 전이 지속시간은 **이 토큰에서만** 정합니다.
     감속 선호(prefers-reduced-motion)는 §2 에서 이 값을 줄일 뿐 전이를 없애지
     않습니다. 새 전이를 넣을 때 .15s 를 손으로 적지 말고 이 토큰을 쓰십시오 —
     그래야 감속 선호가 그 전이에도 자동으로 적용됩니다. */
  --motion-dur:.15s;
  --r-sm:6px; --r-md:10px; --r-lg:14px; --r-pill:999px;
  --shadow-card:0 1px 2px rgba(22,24,29,.06),0 2px 10px rgba(22,24,29,.06);
  /* 🔴 v1.0: rgba(31,58,110,.35) → 불투명 --c-primary.
     구 값은 흰 지면에 얹으면 #B1BACC 로 합성되어 지면 대비 1.95:1 · 입력창
     테두리 대비 1.79:1 이었습니다(WCAG 1.4.11 비텍스트 3:1 미달).
     새 색을 만들지 않았습니다 — 이미 있는 --c-primary 가 흰 지면에서 11.12:1 입니다.
     이 링은 outline(offset 2px)이 남기는 2px 틈을 메워 한 겹으로 보이게 하는
     역할이며, **단독 포커스 지표가 아닙니다.** 고대비 모드에서는 box-shadow 가
     강제로 none 이 되고 그때는 outline 만 남습니다(§9 .input:focus 주석 참조). */
  --shadow-focus:0 0 0 3px var(--c-primary);
}

@media (min-width:768px){
  :root{ --fs-h1:38px; --fs-h2:26px; --fs-h3:19px; --fs-glyph:44px; }
}

/* =============================================================================
   2. 리셋 · 기본
   ========================================================================== */
*,*::before,*::after{ box-sizing:border-box; }
html{ -webkit-text-size-adjust:100%; }
/* 🔴 서체 기본값만 :where() 로 뺐습니다 (0,0,0). 사유는 §3-1 의 「서체 특이도」 주석.
   여기 body{font-family:…} 로 두면 (0,0,1) 이라 §3-1 의 :where(:lang(ja)) 를 이겨서
   **일본어 페이지 본문이 영문 스택으로 그려집니다.** 되돌리지 마십시오. */
:where(body){ font-family:var(--font-en); }
body{
  margin:0;
  background:var(--c-bg);
  color:var(--c-text);
  font-size:var(--fs-body);
  line-height:var(--lh-en);
  overflow-wrap:break-word;   /* 긴 토큰만 끊습니다. anywhere 를 쓰지 않습니다 */
  hyphens:none;
}
h1,h2,h3,h4,p,ul,ol,figure,blockquote,dl,dd{ margin:0; }
ul,ol{ padding:0; list-style:none; }
img,svg{ max-width:100%; }
a{ color:var(--c-primary); }
a:hover{ color:var(--c-primary-dark); }
:focus-visible{ outline:3px solid var(--c-primary); outline-offset:2px; }
.num{ font-variant-numeric:tabular-nums; }
.visually-hidden{
  position:absolute; width:1px; height:1px; margin:-1px; padding:0;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}
.skip{
  position:absolute; left:-9999px; top:0; z-index:100;
  background:var(--c-primary); color:var(--c-text-invert);
  padding:var(--sp-3) var(--sp-4); border-radius:0 0 var(--r-md) 0;
}
.skip:focus{ left:0; }

/* 🔴 v1.1 (P2-3) — 전역 말살에서 「덜 움직이게」로 바꿨습니다.
   구 규칙:  *,*::before,*::after{ transition:none !important; animation:none !important; }
   오늘의 피해는 거의 없었습니다 — 이 저장소의 전이는 .btn 의
   background-color·border-color 두 건뿐입니다. 문제는 **장래**였습니다.
   `*` 에 !important 라, 앞으로 누가 의미 있는 상태 전이를 넣어도 감속 선호
   이용자에게는 **조용히 사라집니다.** 감속 선호는 "움직임을 없애 달라"가 아니라
   "덜 움직이게 해 달라"이고, 상태 변화와 위계는 남아야 합니다.

   그래서 두 가지만 합니다.
     ① --motion-dur 를 .15s → .04s 로 줄입니다. 없애지 않고 줄입니다.
     ② transition 이 붙을 수 있는 속성을 **색 계열로 제한**합니다.
        transform·translate·scale·top·left·width 처럼 **위치와 크기를 바꾸는
        속성은 목록에서 빠지므로 전이 없이 즉시 적용**됩니다. 어지럼증을 만드는
        것은 색이 아니라 이동·확대축소·시차입니다.

   🔴 이 규칙이 「없던 전이를 새로 만들지」 않는 이유 (여기가 가장 틀리기 쉬운 곳입니다)
     transition-property 의 초기값은 `all` 이지만 transition-duration 의 초기값은
     0s 입니다. 그래서 목록만 강제해도 **작성자가 지속시간을 적지 않은 요소에서는
     아무 일도 일어나지 않습니다.** 반대로 여기서 duration 을 `*` 에 강제하면
     모든 요소의 모든 색 변화가 전이되어 **감속 선호 이용자에게 움직임이 늘어납니다.**
     그래서 duration 은 `*` 가 아니라 :root 토큰에서만 줄입니다.

   ⚠ 키프레임 애니메이션(@keyframes)은 이 저장소에 0건이고 그 상태가 검사되고
     있습니다(style-l0.css 머리말 §10-4 · document.getAnimations().length === 0).
     animation-name 의 초기값은 none 이라 duration 강제가 없던 애니메이션을
     만들지는 않으므로, 함께 상한을 걸어 둡니다. */
@media (prefers-reduced-motion:reduce){
  :root{ --motion-dur:.04s; }
  *,*::before,*::after{
    transition-property:background-color,border-color,color,outline-color,box-shadow,opacity,fill,stroke !important;
    animation-duration:var(--motion-dur) !important;
    animation-iteration-count:1 !important;
  }
}

/* =============================================================================
   3. 다국어 조판 (design-guide.md §4 와 1:1 대응)
   ========================================================================== */

/* 3-1. 언어별 폰트·행간·자간·줄바꿈 ------------------------------------------ */
/* 🔴 서체 특이도 — font-family «만» 따로 :where() 로 뺐습니다 (v0.9 정정 2026-08-02)
   -----------------------------------------------------------------------------
   무엇이 문제였나 【확인함 2026-08-02 · 렌더 실측 · design/render-probe.js §12】
     :lang() 은 «그 요소의 언어» 를 보므로 문서의 **모든 요소**에 걸립니다(§4 주석이
     line-height 에 대해 이미 같은 지적을 하고 있습니다). 특이도는 (0,1,0) 이라
       · 요소 셀렉터 h1/h2/h3 = (0,0,1) 를 **이깁니다**
       · 클래스 셀렉터 .brand__name = (0,1,0) 과는 **비깁니다** → 시트 순서가 결정
     그래서 theme-dancheong.css §2 의 「제목은 명조」 규칙 중
       h1 · h2 · h3           → 졌습니다. 실제로 sans 로 그려지고 있었습니다.
       .brand__name 외 클래스 → 이겼지만 **theme 이 나중에 로드되기 때문**이었습니다.
                                시트 순서가 바뀌면 로고도 조용히 sans 가 됩니다.
     즉 증상은 h1 한 곳이지만 원인은 «언어 규칙이 컴포넌트 규칙을 이기는 구조» 입니다.

   무엇을 했나
     font-family 선언만 :where() 로 감싸 (0,0,0) 으로 낮췄습니다. 그러면
       · h1 (0,0,1) 이 항상 이깁니다 — **시트 순서와 무관합니다**
       · 클래스 규칙 (0,1,0) 도 항상 이깁니다 — 순서와 무관합니다
       · 아무 규칙도 없는 요소(언어 전환 링크의 <a lang="ja"> 등)에는 그대로 걸립니다
         — 요소별 언어 전환이라는 원래 목적은 유지됩니다
     §2 의 body{font-family} 도 :where(body) 로 옮겼습니다. (0,0,1) 로 남겨 두면
     이 규칙을 이겨서 일본어 페이지 본문이 영문 스택이 됩니다.

   🔴 나머지 선언(line-height·letter-spacing·word-break·line-break·font-style)은
      **일부러 (0,1,0) 그대로 뒀습니다.** 같이 낮추면 h1 의 letter-spacing:-.01em(0,0,1)이
      일본어의 .02em 을 이겨서 «테마를 싣지 않은 일본어 페이지» 의 제목 자간이
      조용히 바뀝니다. 이번 건과 무관한 회귀라 범위를 넓히지 않았습니다.
      line-height 쪽은 §4 의 h1:lang(en) 3줄이 이미 명시적으로 처리하고 있습니다.
   ⚠ :where() 를 벗기면 h1 이 다시 sans 가 됩니다. design/render-probe.js §12 가
     실제 렌더의 font-family 를 실측해 잡고, design/check-theme-break.js **2부**가
     그 판정이 정말 우는지를 고의 파손으로 확인합니다(5건 · 그중 「시트 순서만 뒤바꿈」은
     반대로 **초록이어야** 통과입니다 — 순서 무관을 증명하는 자리입니다). */
:where(:lang(en)){ font-family:var(--font-en); }
:where(:lang(ja)){ font-family:var(--font-ja); }
:lang(en){
  line-height:var(--lh-en);
  letter-spacing:0;
  word-break:normal;
  line-break:auto;
}
:lang(ja){
  line-height:var(--lh-ja);
  letter-spacing:.02em;
  word-break:normal;   /* keep-all 을 쓰면 일본어가 컨테이너를 넘칩니다 */
  line-break:strict;   /* 禁則処理: 약물·소가나가 행두에 오지 않게 합니다 */
  font-style:normal;   /* 일본어에 이탤릭을 쓰지 않습니다(합성 사체) */
}
:lang(ja) i,:lang(ja) em,:lang(ja) cite{ font-style:normal; font-weight:700; }

/* 3-2. 본문 최대 폭: 언어별로 다릅니다 ------------------------------------- */
.prose{ max-width:var(--measure-en); }
.prose:lang(ja){ max-width:var(--measure-ja); }

/* 3-3. 일본어 최소 글자 크기: 13px 캡션을 쓰지 않습니다 --------------------- */
:lang(ja) .caption,:lang(ja) .hint,:lang(ja) .ad-label,:lang(ja) .foot__meta{
  font-size:var(--fs-sm);
}

/* 3-4. 한자(천간·지지) 글리프 ---------------------------------------------- */
.han{
  font-family:var(--font-han);
  font-weight:400;
  letter-spacing:0;
  line-height:1.1;
  /* 🔴 한자는 글자 단위로 줄바꿈됩니다 — 라틴 문장 안에 낀 두 글자가 갈라집니다.
     실측 【확인함 2026-08-02 · app/en/index.html 768px · .han 의 getClientRects().length = 2】
       Korean Saju 四      ← 여기서 갈라졌습니다
       柱 — an East …
     v1.6 이 히어로 제목 폭을 50% 로 좁히면서 드러났지만, 원인은 폭이 아니라
     «이 글리프 묶음에 줄바꿈 금지가 없다» 는 것입니다. 폭을 되돌려도 더 긴 문장이나
     더 좁은 화면에서 같은 일이 다시 일어납니다. 그래서 폭이 아니라 여기를 고칩니다.
     ⚠ .han 은 1~2글자 글리프 묶음에만 씁니다(四柱·天干·地支·五行·十神). 긴 문장에
       붙이면 nowrap 이 컨테이너를 넘칩니다. 문장에는 쓰지 마십시오.
     ⚠ design/render-probe.js §13 이 실제 렌더에서 «갈라지지 않았는가» 를 봅니다. */
  white-space:nowrap;
}

/* 3-5. 언어 길이 차이를 흡수하는 규칙 --------------------------------------- */
/* 폭을 고정하지 않고, 높이는 min-height 로만 잡고, 말줄임을 쓰지 않습니다.
   ⚠ 2026-08-03 — `.lang__link` 는 아래 §5 ㉤ 에서 white-space 만 nowrap 으로 되돌립니다.
     이 규칙(줄바꿈 허용)이 옳은 것은 «문장» 이 들어가는 상자(.btn·.chip·.badge·.tab)이고,
     언어 전환 링크의 내용은 «日本語» 3글자짜리 고정 라벨입니다. CJK 는 글자 단위로
     갈라지므로(§3-4 .han 과 같은 성질) 여기서는 흡수할 «길이 차이» 가 없고 파손만
     남습니다. width:auto · min-width:0 · overflow:visible 은 그대로 적용됩니다. */
.btn,.chip,.badge,.tab,.lang__link{
  width:auto;
  min-width:0;
  white-space:normal;
  text-overflow:clip;
  overflow:visible;
}

/* =============================================================================
   4. 레이아웃
   ========================================================================== */
.wrap{ width:100%; max-width:var(--maxw); margin:0 auto; padding:0 var(--sp-4); }
.section{ padding:var(--sp-10) 0; }
.section--soft{ background:var(--c-bg-soft); }
.section__head{ margin-bottom:var(--sp-6); }
.layout{ display:block; }

@media (min-width:768px){
  .wrap{ padding:0 var(--sp-6); }
  .section{ padding:var(--sp-16) 0; }
}
@media (min-width:1024px){
  .layout{ display:grid; grid-template-columns:minmax(0,1fr) 300px; gap:var(--sp-8); align-items:start; }
  /* 사이드바 슬롯(AD-RS)은 level 2 입니다. 밀도를 낮춰 슬롯을 끄면 300px 컬럼도 함께 사라집니다.
     .ad-side 자체가 그리드 아이템입니다. 래퍼 <div> 로 감싸지 마십시오 — 빈 행이 남습니다(guide AD-L5·L-3). */
  html:not([data-ad-density="max"]) .layout{ grid-template-columns:minmax(0,1fr); }
}

h1{ font-size:var(--fs-h1); font-weight:800; line-height:1.25; letter-spacing:-.01em; text-wrap:balance; }
h2{ font-size:var(--fs-h2); font-weight:700; line-height:1.3; text-wrap:balance; }
h3{ font-size:var(--fs-h3); font-weight:700; line-height:1.35; }

/* 🔴 제목 행간 복구 — 위 세 줄이 실제로는 적용되지 않고 있었습니다.
   §3-1 의 `:lang(en){ line-height:var(--lh-en) }` 는 **문서의 모든 요소**에 걸립니다
   (:lang() 은 그 요소의 언어를 보는 것이지 조상만 보는 것이 아닙니다).
   특이도가 :lang(en) = (0,1,0) > h1 = (0,0,1) 이므로 h1 의 1.25 가 지고
   본문 행간 1.65 가 제목에도 그대로 적용됐습니다.
   실측 【확인함 — getComputedStyle(h1).lineHeight, design/l0-sample.html】
     375px  h1 28px → 46.2px (=1.65). 4줄 표제가 185px
     1280px h1 38px → 62.7px (=1.65). 2줄 표제가 125px
   같은 특이도로 되돌립니다. craft floor "분명한 스케일·굵기 단계" 항목이자,
   히어로 높이를 모바일에서 50px 줄이는 항목이기도 합니다(진단 P0-1).
   ⚠ 일본어는 값이 다릅니다. CJK 는 라틴보다 글자틀이 꽉 차서 같은 행간이 더 좁아
     보입니다. 본문 1.85 를 그대로 쓰면 제목이 흩어지므로 중간값을 씁니다. */
h1:lang(en){ line-height:1.2; }
h2:lang(en){ line-height:1.3; }
h3:lang(en){ line-height:1.35; }
h1:lang(ja){ line-height:1.35; }
h2:lang(ja){ line-height:1.45; }
h3:lang(ja){ line-height:1.5; }
.lede{ font-size:var(--fs-body); color:var(--c-text-sub); margin-top:var(--sp-3); }
.caption{ font-size:var(--fs-caption); color:var(--c-text-sub); }
/* `.p + .p` 는 §8 로 옮기며 지웠습니다 — 사용처 0건이었습니다. 사유는 §8 주석 참조. */

/* =============================================================================
   5. 헤더 · 네비 · 언어 전환 (JS 0줄)
   ========================================================================== */
.head{ border-bottom:1px solid var(--c-border); background:var(--c-bg); }
.head__bar{ display:flex; align-items:center; gap:var(--sp-3); min-height:60px; }
.brand{ display:inline-flex; align-items:center; gap:var(--sp-2); min-height:var(--tap); font-weight:800; color:var(--c-primary-dark); text-decoration:none; }
.brand__mark{ flex:0 0 auto; }
.brand__name{ font-size:var(--fs-h3); }
.brand__tag{ font-size:var(--fs-caption); color:var(--c-text-sub); font-weight:400; }

/* 🔴 내비 체크박스 — 이 요소가 모바일 메뉴의 **실제 키보드 정지점**입니다.
   `<label class="nav-btn">` 은 포커스를 받지 않으므로 탭으로 도달하는 것은 체크박스이고,
   이름은 `<label for="nav">` 가 줍니다. 따라서 aria-hidden / tabindex="-1" 을
   붙이면 안 됩니다 (WCAG 2.1.1 — `developer` 가 app/ 27페이지에서 제거했습니다). */
.nav-check{ position:absolute; opacity:0; width:1px; height:1px; }
/* ㉠ 포커스 링 — 체크박스가 opacity:0 · 1×1px 이라 **자기 자신에는 링을 그릴 수 없습니다.**
   도달은 되는데 어디에 있는지 보이지 않는 상태였습니다(SC 2.4.7).
   포커스를 인접 형제인 버튼에 그려 줍니다. `developer` 가 `designer` 소관으로 넘긴 항목입니다
   (app/README.md §13-2 ㉠). */
.nav-check:focus-visible + .nav-btn{ outline:3px solid var(--c-primary); outline-offset:2px; }
.nav-btn{
  margin-left:auto; display:inline-flex; align-items:center; justify-content:center;
  min-width:var(--tap); min-height:var(--tap); border:1px solid var(--c-border-strong);
  border-radius:var(--r-md); cursor:pointer; background:var(--c-bg);
}
.nav-list{ display:none; padding:var(--sp-2) 0 var(--sp-4); border-top:1px solid var(--c-border); }
.nav-check:checked ~ .nav-list{ display:block; }
.nav-list a,.lang__link{
  display:flex; align-items:center; min-height:var(--tap);
  padding:var(--sp-2) var(--sp-3); border-radius:var(--r-sm);
  color:var(--c-text); text-decoration:none;
}
.nav-list a[aria-current="page"]{ background:var(--c-primary-tint); color:var(--c-primary-dark); font-weight:700; }
/* 🔴 ㉤ 언어 전환 칸 — 좁은 폭에서 «日本語» 가 두 줄로 갈라졌습니다 (2026-08-03 · designer)
   -----------------------------------------------------------------------------
   사용자 원문: 「영문 어어, 일본어 셀렉하는 칸을 좀 줄이던가 해줘 / 밀려서 다음칸으로
   내려가는게 보기가 안좋네」 (약 490px 실기기 스크린샷).
   🔴 원인은 490px 이 아닙니다 — **잰 여섯 폭 전부에서 갈라져 있었습니다.**
     (375~768 만 쟀습니다. 1024 이상은 안 쟀습니다 【미검증】 — 이 건의 대상 구간이
      아니었고, 넓은 폭은 상자가 안 눌려 갈라질 이유가 없다고 봤습니다.)
     실측 【확인함 2026-08-03 · app/en·ja/index.html 에 design/ 의 CSS 를 걸어 CDP 로 측정 ·
       Range.getClientRects() 의 top 종류 수로 «글자가 몇 줄인가» 를 셈】
         고치기 전  375·420·490·560·640·768 · en·ja 12칸 **전부 日本語 2줄**
       왜 폭과 무관한가 — .lang__link 는 .head__bar 안에서 flex-shrink 로 눌려 늘
       내용 폭보다 좁습니다(§3-5 의 min-width:0). 그 상태에서 §3-5 의 white-space:normal
       이 CJK 를 글자 단위로 쪼갭니다. **§3-4 .han 의 四柱 갈라짐과 같은 결함입니다.**
   고친 방법 — 세 가지를 함께 해야 합니다. 하나만 하면 다른 곳이 무너집니다:
     ① white-space:nowrap  — 갈라짐 자체를 막습니다(.han 과 같은 처방)
     ② 768 미만에서 글자 14px · 좌우 패딩 8px · gap 4px — ① 만 넣으면 상자가 커져
        브랜드 칸을 밀고 **375 에서 머리가 오히려 높아집니다**(실측 en 122→173px).
        ② 까지 넣으면 375 에서 고치기 전과 «같은» 122px 이면서 갈라짐만 사라집니다.
     ③ 768 이상은 원래 크기(16px · 12px)로 되돌립니다 — 아래 미디어 블록.
   실측 머리 높이(headH · en / ja) 【확인함 2026-08-03 · 위와 같은 도구】
       폭   375        420        490        560        640        768
       전   122 / 139  107 / 107  107 / 107  107 / 107  107 / 107  83 / 82
       후   122 / 139   83 /  87   83 /  87   74 /  74   74 /  74  83 / 81
     🔴 어느 폭에서도 «높아지지» 않았고 420~640 에서 20~33px 낮아졌습니다.
   접근성 — 줄인 뒤에도 표적이 남는지 함께 쟀습니다 【확인함 2026-08-03】
     · 상자 실측 en 65.14×44 · ja 60.84×44 (768 미만). WCAG 2.5.8 하한 24×24 를 넘고
       이 저장소 자체 기준 --tap(44) 도 넘습니다. 높이는 min-height:var(--tap) 가 잡습니다.
     · 색은 한 글자도 안 바꿨으므로 대비는 그대로입니다(check-l0-contrast 「nav 링크 vs
       헤더 면」 4.5:1 · 이 검사가 .lang__link 를 함께 봅니다).
   ⚠ 「잠정 — 결정-29 …」 칩이 좁은 폭에서 2~4줄로 접히는 것은 **여기서 못 고칩니다.**
     그 문구는 내용이고 자리는 app/ 마크업입니다. 아래 §5 끝 주석에 근거를 적었습니다.
   ⚠ design/render-probe.js §13-b 가 실제 렌더에서 «갈라지지 않았는가» 를 봅니다. */
.lang{ display:flex; gap:var(--sp-1); padding:var(--sp-2) 0 var(--sp-4); border-top:1px solid var(--c-border); }
.lang__link{
  border:1px solid var(--c-border-strong);
  white-space:nowrap;            /* ① §3-5 의 normal 을 이 상자에서만 되돌립니다 */
  padding:var(--sp-2);           /* ② §5 위 `.nav-list a,.lang__link` 의 8/12 를 8/8 로 */
  font-size:var(--fs-sm);        /* ② 16 → 14. 768 이상에서 되돌립니다 */
}
.lang__link[aria-current="true"]{ background:var(--c-primary-tint); border-color:var(--c-primary); font-weight:700; }

@media (min-width:768px){
  /* ㉡ 768px 이상에서는 .nav-btn 이 display:none 이라 위 포커스 링을 그릴 대상이
     사라집니다. 그런데 체크박스는 opacity:0 일 뿐 display 는 살아 있어서
     **보이지 않는 탭 정지점 1개**로 남았습니다(1280px 실측 탭 가능 17 → 18).
     여기서 함께 끕니다 — 메뉴가 이미 펼쳐져 있으므로 여는 수단이 필요 없습니다.
     `developer` 가 넘긴 항목입니다(app/README.md §13-2 ㉡). */
  .nav-check{ display:none; }
  .nav-btn{ display:none; }
  /* 🔴 ㉢ v0.9-p — ㉡ 을 넣은 뒤 남은 구멍입니다. display:none 인 체크박스도 :checked 는
     계속 일치하므로 위의 `.nav-check:checked ~ .nav-list{display:block}`(선택자 0,2,0)이
     아래 `.nav-list`(0,1,0)를 계속 이깁니다. 그래서 모바일에서 메뉴를 연 채 768px 이상으로
     넓히면 데스크톱 내비가 가로가 아니라 **세로로 쌓여** 헤더가 세 배로 늘어났습니다.
     ㉡ 이 체크박스와 라벨을 둘 다 감췄기 때문에 되돌릴 방법도 없는 갇힌 상태였습니다.
     【확인함 — headless Chrome 1280×700, `<input id="nav">` 에 checked 를 넣고 캡처.
       고치기 전: 내비 세로 4줄 + 헤더 약 180px. 고친 뒤: 가로 1줄 + 헤더 약 78px】
     고침: 같은 선택자를 아래 규칙에 함께 걸어 특정도를 맞춥니다(0,2,0 = 0,2,0).
     동점이면 나중에 온 쪽이 이기고, 미디어 쿼리는 특정도를 더하지 않으므로 이 규칙이
     항상 뒤에 옵니다. 순서를 바꾸지 마십시오. */
  .nav-list,
  .nav-check:checked ~ .nav-list{ display:flex; gap:var(--sp-1); margin-left:auto; border:0; padding:0; }
  .lang{ border:0; padding:0; margin-left:var(--sp-3); gap:var(--sp-2); }
  /* ㉤ ③ — 좁은 폭에서만 줄였던 언어 칸을 원래 크기로 되돌립니다.
     768 이상에서는 옆에 .nav-list 가 함께 서지만 실측상 여유가 있습니다
     (headH en 83 / ja 81 — 고치기 전 83 / 82 와 같거나 1px 낮습니다). */
  .lang__link{ padding:var(--sp-2) var(--sp-3); font-size:var(--fs-body); }
}

/* 🔴 ㉥ 「잠정 — 결정-29 · 상표·도메인 미검증」 칩이 좁은 폭에서 접히는 건 (2026-08-03)
   -----------------------------------------------------------------------------
   같은 스크린샷에서 이 칩도 2줄로 접혀 있었습니다. **CSS 로 고칠 수 없습니다.**
   실측 【확인함 2026-08-03 · 위 ㉤ 와 같은 도구 · .todo-chip 의 가로 실측】
     한 줄로 놓이는 데 필요한 폭 276.63px(en) · 246.13px(ja).
     그 칩이 앉는 자리는 .brand 안이고, 같은 줄에 마크(28) · 「K-BaZi」 · 내비 버튼(44) ·
     언어 칸(130) 과 좌우 여백(32) 이 함께 섭니다. 합이 **560px 근처**이고, 실제로
     560·640 에서는 1줄, 490 이하에서는 2줄 이상입니다(위 ㉤ 표와 같은 실행).
     ⚠ 768 에서 다시 2줄이 됩니다 — 그 폭부터 .nav-list 세 항목이 같은 줄에 서기
       때문입니다. 별건이고 손대지 않았습니다(회의록 §12-9 「헤더 줄바꿈 무너짐(768)」).
   왜 CSS 로 못 고치는가 — 남은 수단이 전부 더 나쁩니다:
     · nowrap → 이 칩만 가로 스크롤을 만듭니다(문장이라 §3-4 ⚠ 의 금지 대상)
     · font-size 축소 → 13px 가 이미 --fs-caption 이고, 더 줄이면 본문 최소 크기를 깹니다
     · 말줄임(ellipsis) → 「미검증」이 잘려 **경고문이 경고를 못 합니다**
   🔴 그러므로 이 폭에서는 **접힐 수밖에 없습니다.** 줄이려면 «문구» 를 줄여야 하고,
      문구는 디자인이 아니라 내용입니다 — 대표/pm 소관입니다(결정-29 · CHK-9 TODO 칩).
      칩 자체는 상표·도메인이 미검증인 동안 유효한 경고라 designer 가 지우지 않습니다
      (theme-dancheong.css §2-1 ④ 에 같은 판단이 있습니다). */

/* =============================================================================
   6. 히어로
   ========================================================================== */
.hero{ padding:var(--sp-10) 0 var(--sp-8); background:linear-gradient(180deg,#F7F9FC 0%,#FFFFFF 100%); }
.hero__pills{ display:flex; flex-wrap:wrap; gap:var(--sp-2); margin-bottom:var(--sp-4); }
.hero__cta{ display:flex; flex-wrap:wrap; gap:var(--sp-3); margin-top:var(--sp-6); }

/* =============================================================================
   7. 컴포넌트 — 버튼 / 칩 / 배지
   ========================================================================== */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:var(--sp-2);
  min-height:52px; padding:var(--sp-3) var(--sp-5);
  border:1px solid transparent; border-radius:var(--r-md);
  font:inherit; font-weight:700; text-decoration:none; cursor:pointer;
  /* 시간은 --motion-dur 에서만 옵니다. 감속 선호에서 이 값이 .04s 로 줄어들되
     전이 자체는 남습니다(§2 P2-3 주석). 여기에 .15s 를 손으로 적지 마십시오. */
  transition:background-color var(--motion-dur) ease,border-color var(--motion-dur) ease;
}
.btn--primary{ background:var(--c-primary); color:var(--c-text-invert); }
.btn--primary:hover{ background:var(--c-primary-dark); color:var(--c-text-invert); }
.btn--ghost{ background:var(--c-bg); color:var(--c-primary-dark); border-color:var(--c-border-strong); }
.btn--ghost:hover{ background:var(--c-primary-tint); border-color:var(--c-primary); }
.btn--sm{ min-height:var(--tap); padding:var(--sp-2) var(--sp-4); font-size:var(--fs-sm); }
.btn--block{ width:100%; }
.btn[disabled],.btn[aria-disabled="true"]{ background:#E4E8EE; color:#79808C; border-color:#E4E8EE; cursor:not-allowed; }

.chip{
  display:inline-flex; align-items:center; min-height:var(--tap);
  padding:var(--sp-2) var(--sp-4); border:1px solid var(--c-border-strong);
  border-radius:var(--r-pill); background:var(--c-bg); font-size:var(--fs-sm); cursor:pointer;
}
.chip[aria-pressed="true"]{ background:var(--c-primary-tint); border-color:var(--c-primary); font-weight:700; color:var(--c-primary-dark); }

.badge{
  display:inline-flex; align-items:center; gap:var(--sp-1);
  padding:var(--sp-1) var(--sp-3); border-radius:var(--r-pill);
  background:var(--c-primary-tint); color:var(--c-primary-dark);
  font-size:var(--fs-caption); font-weight:700; line-height:1.5;
}
.badge--plain{ background:var(--c-bg-soft); color:var(--c-text-sub); border:1px solid var(--c-border); }

/* TODO 칩 — 배포 전 0개가 되어야 합니다 (design-guide.md §9) */
.todo-chip{
  display:inline-flex; align-items:center; gap:var(--sp-1);
  padding:2px var(--sp-2); border:1px solid var(--c-todo-border); border-radius:var(--r-sm);
  background:var(--c-todo-tint); color:var(--c-todo-text);
  font-family:var(--font-mono); font-size:var(--fs-caption); font-weight:700; line-height:1.5;
}

/* =============================================================================
   8. 카드 · 표 · 안내 박스
   ========================================================================== */
.grid{ display:grid; gap:var(--sp-4); }
@media (min-width:768px){ .grid--3{ grid-template-columns:repeat(3,1fr); } .grid--2{ grid-template-columns:repeat(2,1fr); } }

.card{
  background:var(--c-bg); border:1px solid var(--c-border); border-radius:var(--r-lg);
  padding:var(--sp-5); box-shadow:var(--shadow-card);
}
.card__title{ margin-bottom:var(--sp-2); }
.card__body{ color:var(--c-text-sub); }
/* 🔴 v1.1 (감사 P3-1) — 장문 본문의 간격 리듬
   -----------------------------------------------------------------------------
   원인은 CSS 토큰이 아니라 **생성기가 찍는 인라인 style 이었습니다.**
   지적된 3페이지의 인라인 style 은 정확히 16개이고 그중 10개가 margin-top:16px 입니다
   (탐지기가 센 「16회 중 10회」가 바로 이 16개입니다) 【확인함 —
    grep -o 'style="margin-top:[0-9]*px"' app/en/guides/what-is-saju/index.html | sort | uniq -c
    → 16px 10 · 32px 4 · 8px 2. 세 페이지 모두 같은 분포】.
   인라인 선언은 명시도에서 클래스 규칙을 이기므로, **여기서 무엇을 적어도
   지금은 아무 일도 일어나지 않습니다.** 활성 조건은 `developer` 가
   app/tools/gen-content-pages.js 에서 그 인라인 style 을 지우는 것입니다
   (생성기는 designer 소관이 아닙니다 — 보고에 인계 항목으로 적었습니다).

   ⚠ 그래서 이 규칙은 지금 화면을 한 픽셀도 바꾸지 않습니다. 저장소 전체에서
     인접한 .card__body 쌍 204개가 **전부** 인라인 여백을 달고 있습니다
     【확인함 — 전 HTML 주사, 여백 없는 쌍 0건】. 인계가 끝나야 효과가 납니다.

   리듬 — 제목 «위» 가 «아래» 보다 넓어야 합니다
     절 사이(h2 위)  40px(768px↑ 48px)   ← 종전 인라인 32px
     제목 아래        8px  (.card__title 의 margin-bottom)
     문단 사이       16px
   종전 대비 32:16 = 2.0 이던 것이 40:16 = 2.5 · 40:8 = 5.0 이 됩니다.
   묶음은 좁게, 절은 넓게 — 값을 늘린 것이 아니라 **차이를 늘린 것**입니다.

   ⚠ 여기 있던 `.p + .p{ margin-top:var(--sp-4); }` 를 지웠습니다.
     `.p` 클래스는 app/ 27페이지와 design/ 4페이지를 통틀어 **사용처가 0건**이었습니다
     【확인함 — 전 HTML grep】. 이름은 「문단 사이 여백」인데 실제로는 아무 문단에도
     닿지 않는 규칙이었고, 그 자리가 비어 있었기 때문에 생성기가 인라인으로
     같은 일을 하게 된 것으로 보입니다. 이름과 내용을 맞춥니다. */
.card__body + .card__body{ margin-top:var(--sp-4); }
.card__body + .card__title,
.card__title + .card__title{ margin-top:var(--sp-10); }
@media (min-width:768px){
  .card__body + .card__title,
  .card__title + .card__title{ margin-top:var(--sp-12); }
}
.card--link{ text-decoration:none; color:inherit; display:block; min-height:var(--tap); }
.card--link:hover{ border-color:var(--c-primary); background:var(--c-primary-tint); color:inherit; }

.tablewrap{ overflow-x:auto; }
.table{ width:100%; border-collapse:collapse; font-size:var(--fs-sm); }
.table caption{ text-align:left; font-size:var(--fs-caption); color:var(--c-text-sub); padding-bottom:var(--sp-2); }
.table th,.table td{ border-bottom:1px solid var(--c-border); padding:var(--sp-3); text-align:left; vertical-align:top; }
.table thead th{ background:var(--c-bg-soft); font-weight:700; }
.table th[scope="row"]{ background:transparent; color:var(--c-text-sub); font-weight:700; }

/* 🔴 좌측 5px accent border 를 없앴습니다 (v0.9 · craft floor).
   원문: "A colored border-left or border-right above 1px on cards, list items,
   callouts, or alerts" — 독립 진단(detect.mjs)도 `side-tab` 으로 같은 곳을 지목했고,
   진단 A 는 이 계열(5개)을 "가장 카테고리 교환 가능한 장치"로 지목했습니다.

   🔴 **눈에 덜 띄게 만든 것이 아닙니다.** .notice 는 법적으로 실려 있어야 하는
   오락 목적 고지의 그릇이므로 강도를 유지해야 합니다. 강도를 옮긴 곳은 두 군데입니다.
     ① 한쪽 5px → **사방 2px**. 잉크 총량이 오히려 늘어납니다
        (96×600 기준: 좌측탭 5px = 480px² · 사방 추가 1px = 1,392px²).
     ② 제목이 있는 경우 그 제목을 **채운 칩**으로 올립니다.
        흰 글자 vs --c-notice 는 5.91:1 로 AA 를 넘습니다(check-l0-contrast.js 로 검사).
   ⚠ 색·문안·min-height 는 건드리지 않았습니다. 고지 본문 7.40:1 은 그대로입니다.
   ⚠ .notice__title 은 result-sample.html 에만 있고 l0/l1a 에는 없습니다.
     그래서 ①만으로도 강도가 유지되도록 설계했습니다 — 제목 없는 고지에서
     ②가 사라져도 ①이 남습니다(라벨을 바깥 컨테이너에 두는 것과 같은 원리). */
.notice{
  border:2px solid var(--c-notice);
  background:var(--c-notice-tint); color:var(--c-notice-text);
  border-radius:var(--r-md); padding:var(--sp-4);
  min-height:96px;              /* 문안 교체 대비 하한(L-2 는 v0.2 잠정안). guide §7-3 · §8-2 D-2 */
}
.notice__title{
  display:inline-block; margin-bottom:var(--sp-3);
  padding:2px var(--sp-3); border-radius:var(--r-sm);
  background:var(--c-notice); color:var(--c-text-invert);
  font-weight:800; font-size:var(--fs-sm); line-height:1.6;
}
.notice--todo{ background:var(--c-todo-tint); border-color:var(--c-todo-border); color:var(--c-todo-text); }
.notice--compact{ min-height:64px; padding:var(--sp-3) var(--sp-4); font-size:var(--fs-sm); }

.privacy-line{
  display:flex; gap:var(--sp-2); align-items:flex-start;
  border:1px solid var(--c-border); border-radius:var(--r-md);
  background:var(--c-bg-soft); padding:var(--sp-3) var(--sp-4);
  font-size:var(--fs-sm); color:var(--c-text-sub);
}

/* =============================================================================
   9. 입력 폼
   ========================================================================== */
.field{ margin-bottom:var(--sp-5); }
.field__label{ display:block; font-weight:700; margin-bottom:var(--sp-2); }
.field__row{ display:grid; grid-template-columns:repeat(3,1fr); gap:var(--sp-3); }
.input,.select{
  width:100%; min-height:52px; padding:var(--sp-3) var(--sp-4);
  font-family:inherit; font-size:var(--fs-body); color:var(--c-text);
  background:var(--c-bg); border:1px solid var(--c-border-strong); border-radius:var(--r-md);
}
/* 🔴 v1.0: outline:none 을 지웠습니다. 지우기만 하면 되는 일이었습니다.
   구 규칙은 .input:focus(명시도 0,2,0)로 전역 :focus-visible(0,1,0)의
   3px --c-primary 링(11.12:1)을 **꺼 버렸고**, 남는 표시는 1.95:1 짜리
   그림자뿐이었습니다. 전역 규칙은 멀쩡한데 이 한 줄이 그것을 껐습니다.
   이제 포커스 표시를 담당하는 것은 111행의 전역 :focus-visible 입니다.
   ⚠ border-color 변화는 보조입니다. 색만으로 상태를 전달하지 않도록,
     굵기 3px 의 outline 이 형태 변화까지 만들어 냅니다.
   ⚠ 여기에 outline:none 을 다시 넣지 마십시오.
     check-l0-contrast.js 의 CSS 위생 검사가 잡아 FAIL 시킵니다. */
.input:focus,.select:focus{ border-color:var(--c-primary); box-shadow:var(--shadow-focus); }
.hint{ display:block; margin-top:var(--sp-2); font-size:var(--fs-caption); color:var(--c-text-sub); }
.err{ display:block; margin-top:var(--sp-2); font-size:var(--fs-sm); font-weight:700; color:var(--c-error-text); }
/* 조작 대상은 <label class="check"> 전체입니다(최소 44px, 행 전체 클릭 가능).
   네이티브 체크박스 상자 자체는 24px 이며, 이는 문서화된 예외입니다. guide §10-3 */
.check{ display:flex; gap:var(--sp-3); align-items:center; min-height:var(--tap); padding:var(--sp-2) 0; cursor:pointer; }
.check input{ width:24px; height:24px; flex:0 0 auto; }
.form-actions{ margin:var(--sp-6) 0 var(--sp-4); }
/* [광고 금지 구역] .form-actions 의 형제로 광고 슬롯을 두지 마십시오 (guide §7-5) */

/* =============================================================================
   10. 결과 카드 · 사주 원국 · 오행 분포
   ========================================================================== */
.result{
  border:2px solid var(--c-primary); border-radius:var(--r-lg);
  background:var(--c-bg); overflow:hidden;
}
.result__head{ background:var(--c-primary-tint); padding:var(--sp-4) var(--sp-5); border-bottom:1px solid var(--c-border); }
.result__title{ color:var(--c-primary-dark); }
.result__input{ font-size:var(--fs-sm); color:var(--c-text-sub); margin-top:var(--sp-1); }
.result__body{ padding:var(--sp-5); }
.result__block+.result__block{ margin-top:var(--sp-8); }

.pillars{ display:grid; grid-template-columns:repeat(2,1fr); gap:var(--sp-3); }
@media (min-width:480px){ .pillars{ grid-template-columns:repeat(4,1fr); } }
.pillar{
  border:1px solid var(--c-border); border-radius:var(--r-md);
  padding:var(--sp-3); text-align:center; background:var(--c-bg);
}
.pillar__cap{ font-size:var(--fs-caption); color:var(--c-text-sub); font-weight:700; }
.pillar__glyph{ display:block; font-size:var(--fs-glyph); margin:var(--sp-2) 0 var(--sp-1); }
.pillar__rom{ display:block; font-size:var(--fs-sm); font-weight:700; }
.pillar__meta{ display:block; font-size:var(--fs-caption); color:var(--c-text-sub); }
.pillar__part+.pillar__part{ margin-top:var(--sp-3); padding-top:var(--sp-3); border-top:1px dashed var(--c-border); }
.pillar--unknown{ background:var(--c-bg-soft); border-style:dashed; }
.pillar--unknown .pillar__glyph{ color:var(--c-text-sub); }

.elems{ display:grid; gap:var(--sp-3); }
.elem{ display:grid; grid-template-columns:minmax(88px,auto) 1fr minmax(52px,auto); gap:var(--sp-3); align-items:center; }
.elem__name{ font-weight:700; font-size:var(--fs-sm); display:inline-flex; align-items:baseline; gap:var(--sp-2); }
.elem__glyph{ font-family:var(--font-han); font-size:var(--fs-h3); }
.elem__bar{ display:block; height:14px; background:var(--c-bg-soft); border:1px solid var(--c-border); border-radius:var(--r-pill); overflow:hidden; }
.elem__fill{ display:block; height:100%; width:calc(var(--pct,0) * 1%); }
.elem__count{ font-size:var(--fs-sm); text-align:right; font-variant-numeric:tabular-nums; }
.elem--wood  .elem__glyph,.elem--wood  .elem__name{ color:var(--c-wood-text); }
.elem--fire  .elem__glyph,.elem--fire  .elem__name{ color:var(--c-fire-text); }
.elem--earth .elem__glyph,.elem--earth .elem__name{ color:var(--c-earth-text); }
.elem--metal .elem__glyph,.elem--metal .elem__name{ color:var(--c-metal-text); }
.elem--water .elem__glyph,.elem--water .elem__name{ color:var(--c-water-text); }
.elem--wood  .elem__fill{ background:var(--c-wood); }
.elem--fire  .elem__fill{ background:var(--c-fire); }
.elem--earth .elem__fill{ background:var(--c-earth); }
.elem--metal .elem__fill{ background:var(--c-metal); }
.elem--water .elem__fill{ background:var(--c-water); }

/* 계산 근거 공개 블록 (V-1) */
.basis{ border:1px solid var(--c-border); border-radius:var(--r-md); background:var(--c-bg-soft); padding:var(--sp-4); }
.basis .table td,.basis .table th{ border-bottom-color:var(--c-border); }

/* 전통 해석 인용 블록 — 주어가 '전통'임이 시각적으로 드러나야 합니다.
   🔴 v0.9: 좌측 5px accent border 제거 (craft floor · .notice 와 같은 이유).
   "주어가 전통"이라는 신호를 탭이 아니라 **인용 구조**가 냅니다 —
   틴트 면 + 사방 1px 테두리 + 출처 줄을 가로선으로 분리한 3단.
   가로선이 생기면서 "본문 / 출처" 두 부분이 눈에 나뉘고, 그것이 좌측 탭보다
   'inline quotation with attribution' 을 더 정확히 말합니다.
   ⚠ 출처가 확정되기 전까지 .tradition__src 에는 TODO 칩이 남아 있어야 합니다(L-3). */
.tradition{
  border:1px solid var(--c-primary); background:var(--c-primary-tint);
  border-radius:var(--r-md); padding:var(--sp-4) var(--sp-5); margin:0;
}
.tradition__src{
  display:block; margin-top:var(--sp-3); padding-top:var(--sp-3);
  border-top:1px solid var(--c-primary);
  font-size:var(--fs-caption); color:var(--c-text-sub);
}

/* =============================================================================
   11. FAQ (JS 0줄)
   ========================================================================== */
.faq{ border-top:1px solid var(--c-border); }
.faq__item{ border-bottom:1px solid var(--c-border); }
.faq__q{
  display:flex; gap:var(--sp-3); align-items:center; justify-content:space-between;
  min-height:var(--tap); padding:var(--sp-4) 0; font-weight:700; cursor:pointer; list-style:none;
}
.faq__q::-webkit-details-marker{ display:none; }
.faq__q::after{ content:"+"; font-weight:800; color:var(--c-primary); font-size:var(--fs-h3); }
.faq__item[open] .faq__q::after{ content:"\2212"; }
.faq__a{ padding:0 0 var(--sp-4); color:var(--c-text-sub); }

/* =============================================================================
   12. ★ 광고 슬롯 — 라벨은 슬롯 바깥, 교체 대상은 슬롯 안쪽뿐
       (design-guide.md §7 과 1:1 대응. 임의 변경 금지)
   ========================================================================== */

/* 12-1. 2층 구조 ----------------------------------------------------------- */
.ad-slot-wrap{ margin:var(--ad-gap) 0; }
.ad-slot-wrap--afterresult{ margin-top:var(--ad-gap-afterresult); }

/* 🔴 v1.1 (P2-1): color 가 --c-text-sub 에서 --c-ad-label 로 바뀌었습니다.
   **값은 같습니다**(#565E6B). 라이트 화면은 한 픽셀도 달라지지 않습니다.
   바뀐 것은 「무엇에 매달려 있는가」입니다 — --c-text-sub 는 다크에서 밝은 색으로
   뒤집히는 토큰이고, 라벨이 거기 매달려 있으면 색 구성이 바뀌는 순간 AD-L15 의
   확정값 6.54:1 이 조용히 낡습니다. 라벨은 뒤집히지 않는 토큰에 매답니다. */
.ad-label{
  display:block; margin-bottom:var(--sp-2);
  font-size:var(--fs-caption); font-weight:600; line-height:1.5;
  color:var(--c-ad-label); letter-spacing:.04em;
}

.ad-slot{
  display:flex; align-items:center; justify-content:center;
  overflow:hidden;
  background:var(--c-ad-surface); border:1px solid var(--c-ad-border); border-radius:var(--r-md);
}
.ad-slot--inline{ min-height:var(--ad-h-inline); }
.ad-slot--side{ min-height:var(--ad-h-side); max-width:300px; }
.ad-slot__placeholder{ font-size:var(--fs-caption); color:var(--c-text-sub); padding:var(--sp-3); text-align:center; }

.ad-side{ display:none; }
@media (min-width:1024px){
  .ad-side{ display:block; position:sticky; top:var(--sp-4); }
}

/* 12-2. 광고 밀도 스위치 — 슬롯 개수를 수익 조절 변수로 다룹니다 -------------
   레벨 0 = 항상 노출 / 1 = base·max / 2 = max 에서만.
   반드시 .ad-slot-wrap · .ad-side (= 라벨을 품은 컨테이너) 단위로 껐다 켭니다.
   .ad-slot 만 끄면 라벨만 남아 "광고 없는 광고 라벨"이 됩니다. */
html:not([data-ad-density="max"]) [data-ad-level="2"]{ display:none !important; }
html[data-ad-density="min"] [data-ad-level="1"]{ display:none !important; }

/* 12-3. 구조 위반을 화면에 드러내는 가드 (개발 중 조기 발견용) --------------- */
.ad-slot-wrap:not(:has(> .ad-label)),
.ad-side:not(:has(> .ad-label)){
  outline:4px dashed var(--c-error); outline-offset:4px;
}
.ad-slot-wrap:not(:has(> .ad-label))::before,
.ad-side:not(:has(> .ad-label))::before{
  content:"AD LABEL MISSING - DO NOT DEPLOY";
  display:block; padding:var(--sp-2);
  background:var(--c-error); color:#FFFFFF;
  font-family:var(--font-mono); font-size:var(--fs-caption); font-weight:700;
}
:not(.ad-slot-wrap):not(.ad-side) > .ad-slot{ outline:4px dashed var(--c-error); outline-offset:4px; }
:not(.ad-slot-wrap):not(.ad-side) > .ad-slot::after{
  content:"AD SLOT OUTSIDE LABEL CONTAINER - DO NOT DEPLOY";
  padding:var(--sp-2); background:var(--c-error); color:#FFFFFF;
  font-family:var(--font-mono); font-size:var(--fs-caption); font-weight:700;
}

/* =============================================================================
   13. 시안 전용 표시(specimen) — 실서비스 페이지에 넣지 않습니다
   ========================================================================== */
.specimen{ border:2px dashed var(--c-border-strong); border-radius:var(--r-lg); padding:var(--sp-5); background:var(--c-bg-soft); }
.specimen__tag{
  display:inline-block; margin-bottom:var(--sp-3); padding:2px var(--sp-2);
  border:1px solid var(--c-border-strong); border-radius:var(--r-sm);
  font-family:var(--font-mono); font-size:var(--fs-caption); color:var(--c-text-sub);
}
.specimen__pair{ display:grid; gap:var(--sp-4); }
@media (min-width:768px){ .specimen__pair{ grid-template-columns:1fr 1fr; } }

/* =============================================================================
   14. 푸터
   ========================================================================== */
.foot{ border-top:1px solid var(--c-border); background:var(--c-bg-soft); padding:var(--sp-10) 0; margin-top:var(--sp-10); }
.foot__cols{ display:grid; gap:var(--sp-6); }
@media (min-width:768px){ .foot__cols{ grid-template-columns:2fr 1fr 1fr; } }
.foot__title{ font-size:var(--fs-sm); font-weight:800; margin-bottom:var(--sp-3); }
.foot__list li a{ display:flex; align-items:center; min-height:var(--tap); color:var(--c-text); text-decoration:none; }
.foot__list li a:hover{ text-decoration:underline; }
.foot__meta{ font-size:var(--fs-caption); color:var(--c-text-sub); }
.foot__meta dt{ font-weight:700; }
.foot__meta dd{ margin:0 0 var(--sp-2); }
/* max-width: 독립 진단이 `line-length` 165자를 이 요소에서 재었습니다.
   .prose 가 붙지 않은 <p> 가 wrap 전폭(1120px ≈ 140ch)까지 늘어난 것입니다.
   craft floor 본문 measure 65~75ch → --measure-en(66ch) 을 그대로 씁니다. */
.foot__bottom{ margin-top:var(--sp-8); padding-top:var(--sp-4); border-top:1px solid var(--c-border); font-size:var(--fs-caption); color:var(--c-text-sub); max-width:var(--measure-en); }

/* =============================================================================
   15. 🔴 다크 모드 — OS 선호만 따릅니다 (감사 P2-1)
   -----------------------------------------------------------------------------
   ★ 새 팔레트를 만들지 않았습니다. 아래 색은 **전부 style-l0.css 가 이미 들고
     있고 check-l0-contrast.js 가 이미 재고 있는 값**입니다. 한 일은 L0 장식층의
     먹빛 세계를 기본층 토큰에 배선한 것뿐입니다. 대응은 아래 표에 적었습니다.

     기본층 토큰          다크 값     style-l0.css 의 출처
     --c-bg              #0A0705    --k-ground        (지면)
     --c-bg-soft         #191210    --k-surface       (읽는 면)
     --c-primary-tint    #241A16    --k-surface-2     (한 단 위 면)
     --c-text            #F2E4CC    --k-on-surface
     --c-text-sub        #D6C3A2    --k-on-surface-sub
     --c-primary         #F0C878    --k-focus / --k-on-surface-link
     --c-primary-dark    #FBF3E4    --k-on-surface-strong  (다크에서 hover 는 밝아지는 쪽 · K-24)
     --c-border          #4A3A2A    --k-disabled-line (약한 구분선)
     --c-border-strong   #7A5A3A    --k-surface-line  (3:1 을 담당하는 선)
     .btn--primary 면    #BD0520    --k-crimson       / hover #E50626 --k-crimson-lift
     .btn--primary 선    #D1A558    --k-brass         (--k-btn-line)

   🔴 토글 UI 를 만들지 않았습니다. `prefers-color-scheme` 만 봅니다.
     토글은 선택 상태를 저장해야 하고 이 사이트는 저장을 하지 않습니다(결정-2).
     UA 가 그리는 부분(폼 컨트롤·스크롤바)은 §1 의 `color-scheme:light dark` 가 맡습니다.

   🔴 여기서 **덮어쓰면 안 되는 토큰** — 규칙이지 취향이 아닙니다
     --c-notice · --c-notice-tint · --c-notice-text   오락 목적 고지(법무 L-2).
         본문 7.40:1 은 확정값이고 문안은 designer 소관이 아닙니다. 고지는
         다크에서도 **자기 밝은 tint 를 그대로** 유지합니다 — L0 가 v0.8 에서
         내린 것과 같은 결정입니다(style-l0.css K-8).
     --c-ad-panel · --c-ad-label · --c-ad-surface · --c-ad-border   AD-L15 · AD-L19.
     --c-text-invert   .notice__title 흰 글자(4.5:1)가 여기 걸려 있습니다.
     이 6개를 아래 블록에서 재선언하면 check-l0-contrast.js 의 위생 검사가 FAIL 시킵니다.
     완화하려면 **먼저 17절에 대체 측정 항목을 넣고** 그 다음에 규칙을 손대십시오.

   ⚠ 아래 :root 블록에는 var() 를 쓰지 않고 HEX 를 직접 적습니다.
     검사기가 이 블록을 읽어 값을 가져가는데(17절 dtoken), var() 를 쓰면 라이트
     선언을 먼저 만나 **다크 검사가 라이트 값을 재는** 조용한 오류가 생깁니다.
   ========================================================================== */
@media (prefers-color-scheme:dark){
  :root{
    --c-primary:#F0C878;
    --c-primary-dark:#FBF3E4;
    --c-primary-tint:#241A16;
    --c-text:#F2E4CC;
    --c-text-sub:#D6C3A2;
    --c-bg:#0A0705;
    --c-bg-soft:#191210;
    --c-border:#4A3A2A;
    --c-border-strong:#7A5A3A;

    /* 오행 — 다크에서는 **면색과 텍스트색의 역할이 뒤집힙니다.**
       라이트에서 tint 였던 밝은 색이 어두운 면 위의 글자·막대가 되고,
       어두웠던 -text 색은 글자로 쓸 수 없습니다(먹빛 면 위 1.5:1 대).
       새 색을 만들지 않고 **이미 있는 tint 값을 그대로 옮겼습니다.**
       ⚠ 대가를 적어 둡니다: 다섯 tint 는 채도가 낮아 서로 구분이 약합니다.
         오행의 구분은 막대 색이 아니라 옆의 한자 글리프와 이름이 담당하며,
         수치는 .elem__count 가 숫자로 중복 전달합니다. */
    --c-wood:#E8F3EC;  --c-wood-text:#E8F3EC;
    --c-fire:#FBECEA;  --c-fire-text:#FBECEA;
    --c-earth:#FAF1DF; --c-earth-text:#FAF1DF;
    --c-metal:#F0F2F5; --c-metal-text:#F0F2F5;
    --c-water:#E7F0F7; --c-water-text:#E7F0F7;

    /* 🔴 유일하게 새로 만든 값입니다. L0 에 오류색이 없어 가져올 데가 없었습니다.
       임의로 고르지 않고 style-l0.css K-1 (c) 가 쓴 공식을 그대로 따랐습니다 —
       원색의 색상·채도를 유지하고 L 만 올립니다.
       --c-error(#B3261E) = H3.2 S71.3% L41.0%  →  L 을 72% 로  →  #EB8A85
       【자체 산출 · K-1 (c) 와 동일 공식】 먹빛 지면 8.14:1 · 읽는 면 7.49:1
       ⚠ .err 은 현재 저장소 어디에서도 쓰이지 않습니다. 그래도 고칩니다 —
         쓰이는 순간 다크에서 1.6:1 로 보이지 않게 되는 함정이기 때문입니다. */
    --c-error-text:#EB8A85;
  }

  /* 히어로 그라디언트는 토큰이 아니라 리터럴이라 자동으로 따라오지 않습니다.
     라이트의 «위가 살짝 어둡고 아래가 흰» 방향을 그대로 뒤집어, 읽는 면에서
     지면으로 내려가게 했습니다(--k-surface → --k-ground). */
  .hero{ background:linear-gradient(180deg,#191210 0%,#0A0705 100%); }

  /* 🔴 «면에 흰 글자» 조합만 따로 뒤집습니다.
     --c-primary 는 다크에서 밝은 금색이 되므로, 그 위에 --c-text-invert(흰색)를
     얹는 두 곳(.skip · .btn--primary)은 토큰 교체만으로는 1.6:1 이 됩니다.
     면을 L0 의 진홍으로 바꾸고 흰 글자를 유지합니다(6.55:1). */
  /* 🔴 자리표시자 — 어둡게 만든 쪽이 책임지는 자리입니다.
     Chrome 은 UA 기본 자리표시자 색을 색 구성과 무관하게 #757575 로 씁니다
     【확인함 — result-sample.html 을 prefers-color-scheme light/dark 로 각각 열고
       getComputedStyle(.input,'::placeholder').color 실측. 양쪽 다 rgb(117,117,117)】.
     흰 지면에서는 4.61:1 이라 통과하지만 먹빛 지면에서는 **4.36:1 로 내려갑니다.**
     제 변경이 만든 하락이므로 여기서 되돌립니다. #8C7659 는 L0 의 --k-disabled-fg
     이고 이미 측정돼 있는 색입니다(먹빛 지면 4.64:1).
     ⚠ 자리표시자를 --c-text-sub 로 올리지 마십시오. 그러면 입력된 값과 구분이
       사라져 «이미 채워져 있다»고 읽힙니다. */
  .input::placeholder{ color:#8C7659; }
  .skip{ background:#BD0520; }
  .btn--primary{ background:#BD0520; border-color:#D1A558; }
  .btn--primary:hover{ background:#E50626; border-color:#D1A558; }
  /* 놋빛 테두리는 장식이 아닙니다 — 진홍 면과 먹빛 지면의 대비는 3.07:1 로
     아슬아슬하고, 버튼의 «형태»를 8.83:1 로 확실히 잡아 주는 것이 이 선입니다. */

  /* 비활성 — 라이트의 #E4E8EE 는 먹빛 지면에서 활성 버튼보다 밝아 «꺼져 있음»이
     뒤집힙니다. L0 K-24 와 같은 값으로 면 쪽에 가라앉힙니다. */
  .btn[disabled],.btn[aria-disabled="true"]{ background:#241A16; color:#8C7659; border-color:#4A3A2A; }

  /* 🔴 광고 — AD-L15 · AD-L19. 라벨의 «색»을 지키기 위해 «면»을 깝니다.
     라벨은 원래 흰 지면 위에 있었습니다(6.54:1). 지면이 먹빛이 되면 그 값이
     깨지므로, L0 K-6/K-23-1 이 한 것과 똑같이 래퍼에 흰 패널을 깔아
     **라벨이 계속 흰 면 위에 있게** 합니다. 색을 바꾸는 쪽이 아니라 면을 지키는 쪽입니다.
     바깥 1px 링 rgba(10,7,5,.55) 도 L0 K-23-1 의 값 그대로입니다(헤일로 저감).
     ⚠ 이 절에 .ad-label 선택자는 나오지 않습니다. 라벨은 규칙의 사정권 밖입니다. */
  .ad-slot-wrap{
    background:var(--c-ad-panel); border-radius:var(--r-lg); padding:var(--sp-4);
    box-shadow:0 0 0 1px rgba(10,7,5,.55);
  }
  /* ⚠ .ad-side 는 .layout 의 300px 컬럼 **그 자체**입니다. box-sizing:border-box
     이므로 좌우 padding 을 주면 안쪽 슬롯이 300px 미만이 되어 300×600 규격이
     깨집니다. 그래서 상하만 띄우고 라벨만 들여씁니다. 색 구성이 레이아웃 폭을
     바꾸면 안 됩니다. */
  .ad-side{
    background:var(--c-ad-panel); border-radius:var(--r-lg); padding:var(--sp-3) 0;
    box-shadow:0 0 0 1px rgba(10,7,5,.55);
  }
  .ad-side .ad-label{ padding-left:var(--sp-3); }
}
