/* 한국어 기술문서 타이포그래피.
   Material 기본값은 Roboto인데 Roboto에는 한글 글리프가 없다. 그래서 한글이
   글자마다 OS 대체 폰트로 떨어지면서 자간·굵기·행간이 흔들린다. 시스템 한글
   폰트로 고정하고, 한국어에 필요한 줄바꿈 규칙을 준다. */
:root {
  --md-text-font-family: -apple-system, "Apple SD Gothic Neo", "Pretendard",
    "Noto Sans KR", "Malgun Gothic", "맑은 고딕", "Segoe UI", sans-serif;
  --md-code-font-family: "JetBrains Mono", "D2Coding", "Cascadia Mono",
    ui-monospace, SFMono-Regular, Consolas, monospace;
}

/* 코드 바탕색. Material 기본 `#f5f5f5`는 흰 바탕과 명도 차가 4%뿐이라 사실상
   흰색으로 보인다. 푸른 기가 도는 회색으로 바꿔 코드 영역이 색으로도 구분되게
   한다. 인라인 코드도 같은 변수를 쓰므로 함께 따라간다.

   다크(slate)도 같은 문제가 있다. 페이지 14%·코드 18%로 4% 차이뿐이다. 라이트와
   달리 코드가 페이지보다 **밝은** 쪽이므로 더 올려서 벌린다. */
[data-md-color-scheme="default"] {
  --md-code-bg-color: #eef2f7;
}
[data-md-color-scheme="slate"] {
  /* 21% -> 15%. 토큰 색을 밝게 올렸으므로 바탕을 함께 내려 대비를 벌린다. 페이지
     배경(14%)과는 여전히 구분되고, 코드 영역이 더 또렷한 덩어리로 잡힌다. */
  --md-code-bg-color: hsla(var(--md-hue), 18%, 15%, 1);
}

/* 한국어는 어절 중간에서 끊으면 급격히 읽기 어려워진다. keep-all이 그것을 막는다.

   본문은 0.7rem(14px)이다. Material 기본값 0.8rem(16px)에서 줄인 이유는
   한글의 글자 크기 체감이 영문과 다르기 때문이다. 영문 소문자는 x-height가 em의
   0.52 정도만 차지하는데 한글은 네모틀을 거의 채운다. 그래서 같은 px에서 한글이
   15~20% 커 보인다. 영문 본문 16px에 맞먹는 한글 크기가 14~15px다.

   14px 아래로는 내리지 않는다. 한글은 자소가 모여 한 글자를 이루므로 작아지면
   받침이 뭉개진다. 라틴 문자보다 하한이 높다. */
.md-typeset {
  font-size: 0.7rem;
  line-height: 1.62;
  word-break: keep-all;
  overflow-wrap: break-word;
}
.md-typeset p, .md-typeset li { letter-spacing: -0.003em; }

/* 제목은 본문 행간을 물려받으면 안 된다. 1.72가 상속되면 제목 하나가 본문 두 줄
   높이를 먹어 화면이 성기게 보인다. 제목은 짧으니 촘촘히 둔다. */
.md-typeset h1, .md-typeset h2, .md-typeset h3,
.md-typeset h4, .md-typeset h5, .md-typeset h6 {
  line-height: 1.35;
  word-break: keep-all;
}
/* 제목 배율. 이전 값(h3 1.1em = 15.4px)은 본문 14px과 1.4px 차이뿐이라 제목이
   본문에서 튀어나오지 않았다. 스크롤하며 구획을 잡을 수 없다는 뜻이다.
   docs.nestjs.com은 본문 15px에 h3 21px(1.4배), h4 18px을 쓴다. 같은 비율로 올린다.

   굵기도 함께 올린다 — Material 기본은 h2가 weight 300, h3가 400이라 크기를 키워도
   가늘어서 무게가 안 잡힌다. Nest의 h3는 700이다. */
.md-typeset h1 { font-size: 2.15em; font-weight: 700; }
.md-typeset h2 { font-size: 1.7em; font-weight: 650; }
.md-typeset h3 { font-size: 1.4em; font-weight: 650; }
.md-typeset h4 { font-size: 1.18em; font-weight: 600; }

/* 문단 간격도 함께 줄인다. 행간을 줄여 놓고 문단 사이가 넓으면 리듬이 어긋난다. */
.md-typeset p { margin: 0.7em 0; }
.md-typeset ul, .md-typeset ol { margin-top: 0.5em; margin-bottom: 0.7em; }
.md-typeset li { margin-bottom: 0.28em; }
.md-typeset li > ul, .md-typeset li > ol { margin-top: 0.28em; }

/* 레이아웃 폭과 산문 폭을 분리한다.

   예전에는 `.md-grid`를 60rem(1200px)으로 묶어 둘을 한꺼번에 해결하려 했다. 그러면
   넓은 화면에서 양옆에 200px 가까운 죽은 공간이 생겨 페이지가 갇혀 보인다. 실제로
   1600px 화면에서 Nest는 88%를 쓰는데 우리는 77%만 썼다.

   레이아웃은 화면을 쓰게 풀고, 읽는 폭은 산문에만 건다. 표·코드·다이어그램은 넓게
   쓰는 편이 낫고 실제로 그 때문에 폭을 키웠던 것이므로, 그것들은 제한하지 않는다. */
.md-grid { max-width: 82rem; }

/* 산문만 읽기 좋은 폭으로. 영문 한 줄 75~85자 범위다. */
.md-typeset > p,
.md-typeset > ul,
.md-typeset > ol,
.md-typeset > blockquote { max-width: 46rem; }

/* 표 — 이 문서군의 핵심 표현 수단이다. 조밀하게, 헤더는 고정 톤으로. */
.md-typeset table:not([class]) { font-size: 0.68rem; line-height: 1.6; display: table; margin: 0.8em 0; }
.md-typeset table:not([class]) th { font-weight: 600; white-space: nowrap; }
.md-typeset table:not([class]) td,
.md-typeset table:not([class]) th { padding: 0.5em 0.9em; }
.md-typeset__table { overflow-x: auto; }

/* 코드 블록은 한글 본문보다 조금 작게 두어야 시각 무게가 맞는다. */
/* 코드는 라틴 monospace다. 한글 본문과 같은 rem이면 오히려 작아 보이므로 맞춰 둔다. */
/* 코드는 본문보다 한 단 크게 둔다. 라틴 monospace는 한글 본문과 같은 rem이면
   오히려 작아 보인다. docs.nestjs.com도 본문 15px에 코드 16px로 코드를 더 크게 둔다. */
/* 코드 행간. 렌더를 재보니 잉크 높이는 Nest 13px, 우리 12px로 비슷한데 행간이
   39px 대 26px로 1.5배 벌어져 있었다. 블록이 세로로 늘어져 보이던 원인은 글자
   크기가 아니라 이 간격이다. Nest 수준으로 좁힌다. */
.md-typeset pre > code { font-size: 0.8rem; line-height: 1.4; }

/* 코드 블록 안쪽 여백. Material 기본은 코드가 테두리에 붙어 답답하다. 산문과
   코드가 번갈아 나오는 문서에서는 블록이 숨 쉴 자리가 있어야 덩어리로 읽힌다. */
.md-typeset .highlight > pre > code { padding: 1.1em 1.2em; }

/* 블록 위아래 간격. 앞 문단과 붙어 있으면 어디까지가 설명이고 어디부터가 코드인지
   한눈에 갈리지 않는다. */
.md-typeset .highlight { margin: 1.3em 0; }
.md-typeset code { word-break: normal; }

/* 코드 블록의 경계.

   Material 기본은 아주 옅은 회색 배경뿐이라 흰 바탕에서 블록이 어디서 시작해
   어디서 끝나는지 눈에 잡히지 않는다. 산문과 코드가 번갈아 나오는 문서에서는
   그 경계가 읽는 흐름을 잡아 주는 표지다.

   테두리를 두르고 위에 언어 이름을 단 띠를 얹는다. 색은 전부 Material 변수라
   light/dark 양쪽에서 같이 따라간다. */
.md-typeset .highlight {
  border: 1px solid var(--md-default-fg-color--lightest);
  border-radius: 0.15rem;
  overflow: hidden;              /* 모서리 둥글기가 안쪽 배경에도 먹게 */
}
.md-typeset .highlight > pre { margin: 0; }

.md-typeset .highlight::before {
  display: block;
  padding: 0.3em 1.1em;
  font-family: var(--md-code-font-family);
  font-size: 0.6rem;
  letter-spacing: 0.03em;
  color: var(--md-default-fg-color--light);
  /* 띠와 코드는 같은 바탕에 두고 선 하나로 나눈다. Material이 파일 이름 띠를
     그리는 방식과 같아서 둘이 섞여 나와도 어긋나지 않는다. */
  background-color: var(--md-code-bg-color);
  border-bottom: 1px solid var(--md-default-fg-color--lightest);
}
.md-typeset .highlight.language-cpp::before { content: "C++"; }
.md-typeset .highlight.language-c::before { content: "C"; }
.md-typeset .highlight.language-csharp::before { content: "C#"; }
.md-typeset .highlight.language-java::before { content: "Java"; }
.md-typeset .highlight.language-kotlin::before { content: "Kotlin"; }
.md-typeset .highlight.language-typescript::before { content: "TypeScript"; }
.md-typeset .highlight.language-javascript::before { content: "JavaScript"; }
.md-typeset .highlight.language-go::before { content: "Go"; }
.md-typeset .highlight.language-rust::before { content: "Rust"; }
.md-typeset .highlight.language-python::before { content: "Python"; }
.md-typeset .highlight.language-bash::before { content: "shell"; }
.md-typeset .highlight.language-console::before { content: "shell"; }
.md-typeset .highlight.language-yaml::before { content: "YAML"; }
.md-typeset .highlight.language-json::before { content: "JSON"; }
.md-typeset .highlight.language-xml::before { content: "XML"; }
.md-typeset .highlight.language-cmake::before { content: "CMake"; }
.md-typeset .highlight.language-ts::before { content: "TypeScript"; }
.md-typeset .highlight.language-jsonc::before { content: "JSON"; }
.md-typeset .highlight.language-ini::before { content: "INI"; }
.md-typeset .highlight.language-toml::before { content: "TOML"; }
.md-typeset .highlight.language-groovy::before { content: "Groovy"; }
.md-typeset .highlight.language-gdscript::before { content: "GDScript"; }
/* ASCII 그림과 실행 출력은 언어가 아니다. 띠 없이 테두리만 남긴다.
   언어를 안 적은 fence도 여기로 들어온다. */
.md-typeset .highlight.language-text::before { display: none; }

/* 파일 이름(`title="..."`)을 단 블록은 Material이 이미 띠를 그린다. 겹친다. */
.md-typeset .highlight:has(span.filename)::before { display: none; }
.md-typeset .highlight span.filename { margin-top: 0; border-radius: 0; }

/* 긴 줄은 가로 스크롤 대신 접는다.

   코드 블록마다 아래에 스크롤 바가 생기면 문서를 훑는 흐름이 그때마다 끊긴다.
   가로 스크롤은 읽는 사람이 한 번 더 조작해야 내용을 볼 수 있다는 뜻이기도 하다.

   접힌 줄이 원래 다음 줄인지 이어진 줄인지 구분되지 않으면 코드를 잘못 읽는다.
   `line_spans`가 줄마다 span을 만들어 주므로 이어지는 줄만 안쪽으로 들여 둔다.

   ASCII 다이어그램(```text)과 mermaid는 제외한다. 칸을 맞춰 그린 그림이라
   접으면 그림이 깨진다. 그쪽은 가로 스크롤이 맞다. */
.md-typeset .highlight:not(.language-text) pre > code {
  white-space: pre-wrap;
  overflow-wrap: break-word;
}
.md-typeset .highlight:not(.language-text) pre > code > span[id^="__span"] {
  display: block;
  padding-left: 2.4em;
  text-indent: -2.4em;
}

/* 그래도 스크롤이 남는 자리(다이어그램·넓은 표)는 바를 얇게 둔다. */
.md-typeset .highlight pre,
.md-typeset__table { scrollbar-width: thin; }

/* 제목 간격 — 구분선을 걷어내고 공간이 구획을 만들게 한다.

   이전에는 구분선을 두고 여백을 줄였는데, 그러면 줄 하나가 더 늘면서도 구획은
   선 하나에만 의존한다. Nest는 선을 쓰지 않고 h3 위에 45px을 둔다 — 제목이 크고
   굵으면 공간만으로 구획이 잡히고, 페이지에서 가로줄이 사라져 한결 정돈돼 보인다. */
.md-typeset h2 { margin-top: 2.4em; margin-bottom: 0.7em; }
.md-typeset h3 { margin-top: 2em; margin-bottom: 0.6em; }
.md-typeset h4 { margin-top: 1.6em; margin-bottom: 0.5em; }

/* 다크 모드에서도 다이어그램은 밝은 종이 위에 그린다.

   문서의 `classDef` 397개는 전부 옅은 파스텔 바탕(#e8f5e9·#e3f2fd·#fff3e0 등)에
   어두운 글씨(#1b5e20·#0d47a1·#bf360c 등) 조합이다. 밝은 화면을 전제로 짠 배색이라
   다크에서 바탕만 그대로 밝고 글씨는 테마 전경색(옅은 회색)으로 덮여 서로 묻힌다.

   노드마다 글씨 색을 되돌리려면 classDef 이름을 CSS에 일일이 나열해야 하고, 새
   이름을 쓸 때마다 빠뜨린 노드가 다시 묻힌다. 대신 다이어그램 블록만 밝은 바탕으로
   되돌려 배색이 의도대로 작동하게 한다.

   **파생 변수도 전부 다시 적어야 한다.** Material은 `:root`에서
   `--md-mermaid-sequence-message-fg-color: var(--md-mermaid-edge-color)`처럼 스무 개
   남짓을 파생시킨다. custom property는 선언된 그 자리에서 값이 정해지므로, 여기서
   `--md-mermaid-edge-color`만 바꿔도 파생값은 이미 `:root`에서 다크 색으로 굳은 뒤다.
   sequence 다이어그램의 화살표 글씨가 안 보였던 이유가 이것이다.

   state·ER 다이어그램은 themeCSS가 `--md-default-*`를 직접 쓰므로 그쪽도 함께 준다. */
[data-md-color-scheme="slate"] .md-typeset .mermaid {
  --paper: #e8ecf0;
  --ink: hsla(200, 18%, 26%, 1);
  --tint: rgba(0, 191, 165, 0.12);
  --line: #00838f;

  background-color: var(--paper);
  border: 1px solid rgba(0, 0, 0, 0.12);
  border-radius: 0.15rem;
  padding: 0.5rem 0.3rem;

  /* 기본 여섯 */
  --md-mermaid-edge-color: var(--ink);
  --md-mermaid-label-fg-color: var(--ink);
  --md-mermaid-label-bg-color: var(--paper);
  --md-mermaid-node-bg-color: var(--tint);
  --md-mermaid-node-fg-color: var(--line);
  --md-accent-bg-color: #ffffff;

  /* :root에서 이미 다크 값으로 굳은 파생 변수들 */
  --md-mermaid-sequence-actor-bg-color: var(--paper);
  --md-mermaid-sequence-actor-fg-color: var(--ink);
  --md-mermaid-sequence-actor-border-color: var(--line);
  --md-mermaid-sequence-actor-line-color: rgba(0, 0, 0, 0.32);
  --md-mermaid-sequence-actorman-bg-color: var(--paper);
  --md-mermaid-sequence-actorman-line-color: var(--line);
  --md-mermaid-sequence-box-bg-color: var(--tint);
  --md-mermaid-sequence-box-fg-color: var(--ink);
  --md-mermaid-sequence-label-bg-color: var(--tint);
  --md-mermaid-sequence-label-fg-color: var(--line);
  --md-mermaid-sequence-loop-bg-color: var(--tint);
  --md-mermaid-sequence-loop-fg-color: var(--ink);
  --md-mermaid-sequence-loop-border-color: var(--line);
  --md-mermaid-sequence-message-fg-color: var(--ink);
  --md-mermaid-sequence-message-line-color: var(--ink);
  --md-mermaid-sequence-note-bg-color: var(--paper);
  --md-mermaid-sequence-note-fg-color: var(--ink);
  --md-mermaid-sequence-note-border-color: var(--ink);
  --md-mermaid-sequence-number-bg-color: var(--line);
  --md-mermaid-sequence-number-fg-color: #ffffff;

  /* themeCSS가 직접 참조하는 테마 색(state cluster·divider, ER entity) */
  --md-default-bg-color: #ffffff;
  --md-default-fg-color--lightest: rgba(0, 0, 0, 0.07);
  --md-default-fg-color--lighter: rgba(0, 0, 0, 0.32);
}

/* 인용(샘플에서 보기 / 계약 소유 문서)은 본문과 확실히 구분한다. */
.md-typeset blockquote { border-left-width: 3px; }

/* Admonition 본문 크기. Material 기본은 본문 `.8rem`에 admonition `.64rem`이라 20%
   작다. 짧은 곁가지 메모라면 그 차이가 위계로 읽히지만, 이 문서군의 note는 본문
   서술이 그대로 들어가는 긴 단락이다. 그러면 같은 글이 상자 안팎에서 크기가 달라져
   읽는 리듬이 끊긴다. 본문과 같은 크기로 맞추고, 구분은 배경색과 테두리가 맡는다.

   본문을 0.7rem으로 낮춘 것은 한글 때문인데(위 §본문 참조) admonition은 따라오지
   않아 12.8px로 남아 있었다. 한글 하한 14px 아래다. */
.md-typeset .admonition,
.md-typeset details {
  font-size: 0.7rem;
  line-height: 1.62;
}
.md-typeset .admonition-title,
.md-typeset summary {
  font-size: 0.7rem;
}

/* 코드 하이라이트 색.

   Material 기본은 number 빨강·special 분홍·function 보라·constant 남색·keyword
   파랑·string 초록으로 비슷한 명도의 여섯 색이 경쟁하고, comment·operator·
   punctuation·variable이 전부 같은 회색이다. 그래서 눈으로 찾는 것(함수·문자열)과
   안 읽어도 되는 것(주석·구두점)이 같은 무게로 보인다.

   규율을 바꾼다 — 색 수를 줄이고 간격을 벌린다.
     · 함수·타입 이름을 가장 밝게 둔다. 코드에서 눈이 먼저 찾는 것이다.
     · keyword는 한색, string·number는 난색으로 갈라 둘이 절대 헷갈리지 않게 한다.
     · comment는 확실히 어둡게 내리고, punctuation은 opacity로 더 물러나게 한다.
   전경·배경 대비는 두 scheme 모두 본문 기준을 넘긴다. */
[data-md-color-scheme="slate"] {
  --md-code-fg-color: #c7d3dc;
  --md-code-hl-comment-color: #66757f;
  --md-code-hl-punctuation-color: #8b9aa5;
  --md-code-hl-operator-color: #ffda98;
  --md-code-hl-variable-color: #ffda98;
  --md-code-hl-keyword-color: #8fd3f4;
  --md-code-hl-string-color: #ffc093;
  --md-code-hl-number-color: #ffc093;
  --md-code-hl-constant-color: #ffc093;
  --md-code-hl-special-color: #ff9a8a;
  --md-code-hl-function-color: #f2f8fc;
  --md-code-hl-name-color: #c7d3dc;
  --md-code-hl-generic-color: #8b9aa5;
}
[data-md-color-scheme="default"] {
  --md-code-fg-color: #24303a;
  --md-code-hl-comment-color: #8a949c;
  --md-code-hl-punctuation-color: #6b7680;
  --md-code-hl-operator-color: #8a5a10;
  --md-code-hl-variable-color: #8a5a10;
  --md-code-hl-keyword-color: #12639e;
  --md-code-hl-string-color: #9a4f16;
  --md-code-hl-number-color: #9a4f16;
  --md-code-hl-constant-color: #9a4f16;
  --md-code-hl-special-color: #b03030;
  --md-code-hl-function-color: #0f1720;
  --md-code-hl-name-color: #24303a;
  --md-code-hl-generic-color: #6b7680;
}
/* 함수·타입 이름이 코드에서 가장 먼저 읽혀야 한다. 색만으로 부족하면 굵기로 받친다. */
.md-typeset .highlight .nf,
.md-typeset .highlight .nc { font-weight: 600; }
/* 구두점은 구조만 알려주면 된다. 읽을 대상이 아니다. */
.md-typeset .highlight .p { opacity: 0.72; }

/* 인라인 코드. 이 문서군은 산문 한 문장에 식별자가 여러 개 박힌다
   (`AddZLinkFramework`, `MaxQueuedApplicationJobs` …). 배경색만 옅게 깔면 문장에
   묻혀서 어디까지가 식별자인지 눈으로 잘라내야 한다. 여백과 테두리를 줘서 칩으로
   떨어뜨린다 — 읽는 사람이 문장을 훑다가 식별자만 건져낼 수 있게. */
.md-typeset :not(pre) > code {
  padding: 0.12em 0.38em;
  border: 1px solid var(--md-default-fg-color--lightest);
  border-radius: 0.15rem;
  font-size: 0.72rem;
}
/* 표 안에서는 칸이 좁으므로 여백만 줄인다. */
.md-typeset table:not([class]) :not(pre) > code { padding: 0.1em 0.3em; }
/* 제목 안의 코드는 제목 크기를 따른다. */
.md-typeset h1 code, .md-typeset h2 code,
.md-typeset h3 code, .md-typeset h4 code { font-size: 0.9em; }

/* 루트 폰트를 화면 폭과 무관하게 고정한다.

   Material은 `@media (min-width:100em)`에서 137.5%, `125em`에서 150%로 루트 폰트를
   키운다. 넓은 모니터에서 본문이 14px -> 15.4px -> 16.8px로 커진다는 뜻이다.
   4K 24인치에 150% 배율이면 CSS 뷰포트가 2560px이라 150% 구간에 걸린다.

   이 문서군의 크기는 한글 기준으로 잡혀 있다(§본문 참조 — 한글은 같은 px에서 영문보다
   15~20% 커 보이므로 14px이 영문 16px에 맞먹는다). 화면이 넓다고 그 보정이 배율로
   흔들리면 안 된다. docs.nestjs.com도 본문을 15px로 고정한다.

   폭이 넓으면 글자를 키우는 대신 `.md-grid`가 공간을 쓴다. */
@media screen and (min-width: 100em) { html { font-size: 125%; } }
@media screen and (min-width: 125em) { html { font-size: 125%; } }

/* 좌측 목차. Material 기본은 12.1rem(242px)에 글자 0.7rem인데, 이 문서군은 장 제목이
   길어서(`8. Session and Actor binding`, `17. Where ZLink fits`) 두 줄로 접히는 항목이
   여럿이다. 접힌 항목이 섞이면 목록의 리듬이 깨지고 스캔이 느려진다. 폭을 넓혀 한 줄에
   담고, 글자도 한 단 올려 본문과 구분되게 한다.

   본문은 `.md-grid`가 남는 폭을 가져가므로 산문 폭(46rem)에는 영향이 없다. */
.md-sidebar--primary { width: 15rem; }
.md-nav { font-size: 0.74rem; line-height: 1.4; }
.md-nav__link { margin-top: 0.5em; }
/* 우측 목차는 항목이 짧으므로 그대로 둔다. */
.md-sidebar--secondary .md-nav { font-size: 0.7rem; }
