/* sqzass documentation
 *
 * Dark first, and one accent. The page is otherwise achromatic, because the
 * colour that matters is in the code: highlighting is the feature this tool
 * does properly, and a second palette competing with it would be noise. The
 * accent is warm on purpose — it sits away from the blues and greens of the
 * syntax theme instead of arguing with them.
 *
 * The accent carries meaning, never decoration: links, the focus ring, the
 * current item, and the rule under the page title. If it is orange, it is
 * something you can go to or something you are on.
 *
 * The +++ rule appears once per page, between the title block and the body.
 * That is the same boundary it marks in a source file: front matter ends,
 * content begins. It is the one decorative-looking thing here and it is not
 * decoration.
 *
 * The theme is chosen by [data-theme], written into the document by the
 * template and overridden from localStorage — not by prefers-color-scheme.
 * The generated highlight stylesheet keys off the same attribute, so the two
 * cannot disagree, including with JavaScript off.
 */

:root {
  color-scheme: dark;

  --paper:   #0e1013;
  --raised:  #171a1e;
  --ink:     #e8eaec;
  --ink-2:   #a7adb4;
  --ink-3:   #6f767e;
  --rule:    #242930;
  --accent:  #f0a15e;

  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans KR",
          "Apple SD Gothic Neo", "Malgun Gothic", Roboto, sans-serif;
  --mono: ui-monospace, "JetBrains Mono", "SF Mono", Menlo, Consolas,
          "Liberation Mono", monospace;

  --measure: 68ch;
  --gutter: clamp(1.25rem, 4vw, 3rem);

  /* 크롬 컨트롤의 치수. 검색·언어·GitHub·테마가 전부 이 값을 쓴다.
     하나만 다른 모양이면 그 하나가 고장난 것처럼 보인다.
     터미널에서 모는 도구라 키캡처럼 다룬다 — 얇은 테두리, 작은 반경. */
  --control-h: 2rem;
  --radius: 3px;
  --masthead-h: 3.5rem;
  /* 한 박자. 값을 여기 한 번만 두면 모든 상호작용이 같은 속도로 반응하고,
     그게 "같은 물건"이라는 느낌을 만든다. */
  --tr: 0.14s ease;

  --s-1: 0.8125rem;
  --s0:  1.0625rem;
  --s1:  1.25rem;
  --s2:  1.5rem;
  --s3:  1.9rem;
  --s4:  2.5rem;
}

:root[data-theme="light"] {
  color-scheme: light;

  --paper:   #fbfbfc;
  --raised:  #f1f3f5;
  --ink:     #14171a;
  --ink-2:   #4a5058;
  --ink-3:   #767d86;
  --rule:    #e2e5e9;
  /* Darker than the dark theme's accent: the same orange that reads clearly on
     near-black fails contrast on near-white. */
  --accent:  #9a4e05;
}

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  /* 목차나 heading anchor를 눌렀을 때 뛰지 않고 미끄러진다. 어디로 갔는지가
     보여야 방금 누른 것과 지금 보는 것을 연결할 수 있다. */
  scroll-behavior: smooth;
}

/* 스크롤바를 사이트의 일부로 다룬다. 코드 블록 하나만 손보고 페이지·사이드바·
   목차·검색 결과를 기본값으로 두면, 스크롤이 생기는 자리마다 다른 물건이 나온다.
   Firefox는 표준 속성을, 나머지는 -webkit- 의사요소를 본다. */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--rule) transparent;
}
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--rule);
  border-radius: 999px;
}
::-webkit-scrollbar-thumb:hover { background: var(--ink-3); }
::-webkit-scrollbar-corner { background: transparent; }

/* 선택 영역. 기본 파랑은 이 사이트의 어느 색과도 관계가 없다. */
::selection {
  background: color-mix(in srgb, var(--accent) 30%, transparent);
  color: var(--ink);
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: var(--s0)/1.7 var(--sans);
  /* Korean does not break inside a word. Without this, browsers split 어절
     mid-word at narrow widths and the text becomes hard to read. */
  word-break: keep-all;
  overflow-wrap: anywhere;
}

a { color: var(--accent); text-underline-offset: 0.2em; transition: color var(--tr); }
a:hover { text-decoration-thickness: 2px; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 2px;
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--paper);
  color: var(--ink);
  padding: 0.6rem 1rem;
  z-index: 10;
}
.skip:focus { left: 0; }

/* ---------- header ---------- */

/* 높이를 고정한다. 내용에 따라 늘어나면 페이지마다 상단바 높이가 달라지고,
   그게 "비율이 이상하다"로 읽힌다.
   align-items는 center다. baseline이면 로고를 품은 브랜드와 옆 내비가 서로
   다른 기준선에 앉아 글자들이 어긋난 것처럼 보인다. */
.masthead {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: clamp(0.75rem, 2.5vw, 2rem);
  height: var(--masthead-h);
  padding: 0 var(--gutter);
  background: var(--paper);
  border-bottom: 1px solid var(--rule);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  flex: none;
  font-family: var(--mono);
  font-size: var(--s1);
  font-weight: 600;
  letter-spacing: -0.03em;
  color: var(--ink);
  text-decoration: none;
  /* 좁은 화면에서 "sqzass"가 한 글자씩 세로로 쪼개지던 자리. */
  white-space: nowrap;
}
.brand:hover { color: var(--accent); }

/* 검은 선화라 다크 배경에서는 그냥 안 보인다. 파일을 두 벌 두는 대신 반전한다 —
   순수 흑백 선화에서는 반전이 정확히 흰 선을 만든다. */
.brand img {
  width: 1.9em;
  height: 1.9em;
  filter: invert(1);
}
:root[data-theme="light"] .brand img { filter: none; }

/* 문서 갈래. 사이드바와 같은 데이터를 한 단계 위에서. */
.sections {
  display: flex;
  align-items: center;
  gap: clamp(0.6rem, 1.6vw, 1.4rem);
  min-width: 0;
  overflow: hidden;
  font-size: var(--s-1);
  white-space: nowrap;
}
.sections a {
  color: var(--ink-2);
  text-decoration: none;
  line-height: var(--masthead-h);
  border-bottom: 2px solid transparent;
}
.sections a { transition: color var(--tr), border-color var(--tr); }
.sections a:hover { color: var(--ink); }
.sections a[aria-current] { color: var(--ink); border-bottom-color: var(--accent); }

.tools {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex: none;
}

/* ---------- chip: 크롬 컨트롤 하나의 모양 ----------
   검색, 언어, GitHub, 테마가 전부 이것이다. 링크든 버튼이든 겉모습은 같아야
   한다 — 사용자에게는 둘 다 "누르는 것"이고, 하나만 맨 텍스트면 그 하나가
   빠뜨린 것처럼 보인다. */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  height: var(--control-h);
  padding: 0 0.6rem;
  font: inherit;
  font-family: var(--mono);
  font-size: var(--s-1);
  line-height: 1;
  color: var(--ink-2);
  background: none;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}
.chip { transition: color var(--tr), background var(--tr), border-color var(--tr); }
.chip:hover {
  color: var(--ink);
  background: var(--raised);
  border-color: var(--ink-3);
}

/* 아이콘만 있는 컨트롤은 정사각이어야 한다. 글자 폭에 따라 너비가 달라지면
   같은 줄의 컨트롤들이 서로 다른 리듬을 갖는다. */
.chip-icon {
  width: var(--control-h);
  padding: 0;
  justify-content: center;
}
.chip-icon svg { display: block; }

/* 버튼은 상태가 아니라 동작을 말한다. 다크에서는 해(→ 라이트로), 라이트에서는 달. */
.theme-toggle .i-moon { display: none; }
:root[data-theme="light"] .theme-toggle .i-sun { display: none; }
:root[data-theme="light"] .theme-toggle .i-moon { display: block; }

.search-trigger { min-width: 11rem; justify-content: space-between; }
.search-trigger kbd {
  font: inherit;
  font-size: 0.7rem;
  color: var(--ink-3);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: 0.1rem 0.3rem;
}

/* ---------- breadcrumb ---------- */

.crumbs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  font-family: var(--mono);
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-bottom: 0.9rem;
}
.crumbs a { color: var(--ink-2); text-decoration: none; }
.crumbs a:hover { color: var(--accent); text-decoration: underline; }
/* 마지막 조각은 현재 위치라 링크가 아니다. 다른 조각과 같은 밝기면 어디까지가
   갈 수 있는 곳인지 읽히지 않는다. */
.crumbs a:last-child { color: var(--ink); }
.crumbs a + a::before { content: "/"; margin-right: 0.5rem; color: var(--rule); }

/* ---------- layout ---------- */

.layout {
  display: grid;
  grid-template-columns: 15rem minmax(0, 1fr) 13rem;
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: start;
  max-width: 84rem;
  margin: 0 auto;
  padding: 2.5rem var(--gutter) 5rem;
}

main { min-width: 0; max-width: var(--measure); }

.sidebar, .toc {
  position: sticky;
  /* 상단바가 sticky이므로 그 아래에 붙는다. */
  top: calc(var(--masthead-h) + 1.5rem);
  font-size: var(--s-1);
  line-height: 1.6;
  max-height: calc(100vh - var(--masthead-h) - 3rem);
  overflow-y: auto;
}

/* 사이드바는 높이를 채운다. 내용 높이에 맞추면 경계선이 목록 끝에서 뚝 끊겨
   구역이 아니라 미완성으로 읽힌다. */
.sidebar { height: calc(100vh - var(--masthead-h) - 3rem); }

/* ---------- sidebar ---------- */

/* <details>다. 넓은 화면에서는 열린 채 고정이라 summary를 감추고, 좁은 화면에서만
   서랍이 된다. 구역을 나누는 건 오른쪽 경계선 하나 — 배경을 따로 깔지 않아도
   사이드바가 본문과 다른 층이라는 게 읽힌다. */
/* 구역을 나누는 건 경계선 하나다. 여기에 면과 라운드를 더 얹어 봤더니 사이드바가
   구역이 아니라 떠 있는 카드로 읽혔다. 층은 항목의 hover와 현재 표시가 만든다 —
   판 전체에 색을 깔면 그 층이 묻힌다. */
.sidebar {
  border-right: 1px solid var(--rule);
  padding-right: 1rem;
}
.sidebar > summary { display: none; }

.nav-tree, .nav-tree ul { list-style: none; margin: 0; padding: 0; }
.nav-tree > li + li { margin-top: 0.15rem; }

/* 갈래 제목. 누르면 접힌다는 걸 셰브런이 말한다 — 텍스트로 쓸 수 없는 자리라
   여기서는 도형을 쓰되, 폰트가 아니라 CSS로 그려서 폴백 문제를 피한다. */
.nav-group > summary {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0.6rem;
  border-radius: var(--radius);
  font-family: var(--mono);
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  cursor: pointer;
  list-style: none;
}
.nav-group > summary::-webkit-details-marker { display: none; }
.nav-group > summary:hover { color: var(--ink); background: var(--raised); }

.nav-group > summary::before {
  content: "";
  width: 0.35rem;
  height: 0.35rem;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(-45deg);
  transition: transform var(--tr);
}
.nav-group[open] > summary::before { transform: rotate(45deg); }

.nav-tree a {
  display: block;
  padding: 0.35rem 0.6rem;
  border-radius: var(--radius);
  color: var(--ink-2);
  text-decoration: none;
}
.nav-tree a { transition: color var(--tr), background var(--tr); }
.nav-tree a:hover { color: var(--ink); background: var(--raised); }

/* 현재 항목은 판 전체 폭을 쓰는 알약이다. 왼쪽 막대 하나보다 훨씬 빨리 눈에 띈다. */
.nav-tree a[aria-current="page"] {
  color: var(--ink);
  font-weight: 600;
  background: var(--raised);
  box-shadow: inset 2px 0 0 var(--accent);
}

.nav-group > ul { margin: 0.1rem 0 0.6rem; padding-left: 0.6rem; }

/* ---------- table of contents ---------- */

.toc ul { list-style: none; margin: 0; padding: 0; }
.toc > ul > li + li { margin-top: 0.15rem; }
.toc ul ul { padding-left: 0.85rem; }
.toc a {
  display: block;
  padding: 0.2rem 0 0.2rem 0.7rem;
  border-left: 2px solid transparent;
  color: var(--ink-3);
  text-decoration: none;
}
.toc a { transition: color var(--tr), border-color var(--tr); }
.toc a:hover { color: var(--ink); }
/* 지금 읽고 있는 자리. ui.js가 스크롤을 보고 표시한다 — 없으면 그냥 목록이다. */
.toc a[aria-current] { color: var(--ink); border-left-color: var(--accent); }

.toc::before {
  content: attr(data-label);
  display: block;
  font-family: var(--mono);
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 0.6rem;
}

/* ---------- title block and the +++ rule ---------- */

/* Mono carries structure -- wordmark, headings, labels, code. The sans face is
   reserved for prose. For a tool you drive from a terminal that split says
   something; it also keeps headings visually adjacent to the commands they
   introduce. Mono runs wide, so the scale is pulled in a step. */
.title-block h1 {
  font-family: var(--mono);
  font-size: var(--s3);
  font-weight: 600;
  letter-spacing: -0.04em;
  line-height: 1.15;
  margin: 0;
}

/* A short accent rule under the title. It is the one place the page states
   "this is where you are" in colour rather than in words. */
.title-block h1::after {
  content: "";
  display: block;
  width: 2.5rem;
  height: 2px;
  margin-top: 0.7rem;
  background: var(--accent);
}

.title-block .lede {
  color: var(--ink-2);
  font-size: var(--s1);
  line-height: 1.55;
  margin: 0.6rem 0 0;
}

/* The front matter fence. Ends the metadata, opens the content -- exactly
   what +++ does in the source file this page was written in. */
.fence {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  font-family: var(--mono);
  font-size: var(--s0);
  font-weight: 500;
  letter-spacing: 0.1em;
  color: var(--ink-3);
  margin: 1.6rem 0 2.25rem;
  user-select: none;
}
.fence::after {
  content: "";
  flex: 1;
  border-top: 1px solid var(--rule);
}

/* ---------- prose ---------- */

.prose > :first-child { margin-top: 0; }

.prose h2, .prose h3, .prose h4 {
  font-family: var(--mono);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.3;
  /* 상단바가 sticky이므로 그 높이만큼 비켜야 한다. 이 값이 작으면 목차를
     눌렀을 때 제목이 상단바 아래로 들어가 보이지 않는다 — 실제로 24px 가렸다. */
  scroll-margin-top: calc(var(--masthead-h) + 1.5rem);
}
.prose h2 { font-size: var(--s2); margin: 2.9rem 0 0.9rem; }
.prose h3 { font-size: var(--s1); margin: 2.25rem 0 0.7rem; }
.prose h4 { font-size: var(--s0); margin: 1.75rem 0 0.5rem; }

/* h2 opens a section; a hairline above it makes that legible at a glance
   without adding another visual device. */
.prose h2 {
  border-top: 1px solid var(--rule);
  padding-top: 2.9rem;
}
.prose h2:first-child { border-top: 0; padding-top: 0; margin-top: 0; }

.prose p, .prose ul, .prose ol { margin: 0 0 1.1rem; }
.prose li + li { margin-top: 0.3rem; }

/* The anchor is there for people who want to link to a section, not for
   everyone else to look at. */
.anchor {
  margin-left: 0.4rem;
  color: var(--ink-3);
  text-decoration: none;
  opacity: 0;
  font-weight: 400;
  transition: opacity var(--tr), color var(--tr);
}
.anchor:hover { color: var(--accent); }
h1:hover > .anchor, h2:hover > .anchor, h3:hover > .anchor,
h4:hover > .anchor, h5:hover > .anchor, h6:hover > .anchor,
.anchor:focus-visible { opacity: 1; }
@media (hover: none) { .anchor { opacity: 1; } }

/* ---------- code ---------- */

.prose code {
  font-family: var(--mono);
  font-size: 0.875em;
  background: var(--raised);
  padding: 0.15em 0.35em;
  border-radius: 3px;
}

.prose pre.highlight {
  position: relative;
  font-family: var(--mono);
  font-size: 0.875rem;
  line-height: 1.6;
  background: var(--raised);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: 0.9rem 1.1rem;
  margin: 0 0 1.3rem;
  overflow-x: auto;

  /* 넘치는 코드에는 스크롤이 있다는 표시가 필요하다. 잘린 줄만 보이고 아무
     힌트가 없으면 사람들은 그게 전부인 줄 안다. 스크롤바 모양은 위쪽 전역
     규칙이 정하고, 여기서는 대비만 한 단계 올린다 — 코드 블록의 면이 본문보다
     밝아서 같은 색이면 묻힌다. */
  scrollbar-color: var(--ink-3) transparent;
}
.prose pre.highlight::-webkit-scrollbar-thumb { background: var(--ink-3); }

/* 복사 버튼. 도구 설정 키가 아니라 이 사이트의 CSS와 JS다 — 문서에도 그렇게
   적어 두었고, 여기가 그 말을 지키는 자리다.
   포커스로도 닿아야 하므로 hover에만 기대지 않는다. */
.copy {
  position: absolute;
  top: 0.45rem;
  right: 0.45rem;
  height: 1.5rem;
  padding: 0 0.45rem;
  font: inherit;
  font-size: 0.7rem;
  color: var(--ink-3);
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--tr), color var(--tr), border-color var(--tr);
  /* 버튼은 pre 안에 있어서, 블록을 통째로 긁어 복사하면 이 라벨까지 따라온다.
     선택에서 빼면 복사문이 코드만 남는다 — 줄 번호 레시피와 같은 이유다. */
  user-select: none;
}
.prose pre.highlight:hover .copy,
.copy:focus-visible { opacity: 1; }
.copy:hover { color: var(--ink); border-color: var(--ink-3); }
.copy[data-done] { color: var(--accent); border-color: var(--accent); opacity: 1; }

/* 터치 화면에는 hover가 없다. 항상 보이게 둔다. */
@media (hover: none) {
  .prose pre.highlight .copy { opacity: 1; }
}
.prose pre.highlight code {
  /* 블록으로 넓혀 두는 이유: hl-line 표시와 data-name 라벨이 이 박스의 폭을
     물려받는다. auto 폭이면 스크롤되는 블록에서 보이는 폭까지만 칠해져서,
     옆으로 넘긴 순간 강조가 사라진 채로 줄의 나머지가 보인다. */
  display: block;
  width: max-content;
  min-width: 100%;
  background: none;
  padding: 0;
  border-radius: 0;
  font-size: inherit;
}

/* 펜스 옵션 `hl_lines=`가 감싼 줄. <mark>의 브라우저 기본(노란 배경, 검은 글자)은
   두 테마 어느 쪽과도 안 맞으므로 악센트 기운의 면으로 바꾼다. 음수 마진으로
   pre의 좌우 패딩까지 칠해 "줄 전체"가 표시된 것으로 읽히게 한다. */
.prose pre.highlight mark.hl-line {
  display: block;
  margin: 0 -1.1rem;
  padding: 0 1.1rem;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  box-shadow: inset 2px 0 0 var(--accent);
  color: inherit;
}

/* 펜스 옵션 `name=`. 빌드는 data-name 속성만 내보내고 보여주는 건 사이트 몫이다 —
   여기가 그 몫을 하는 자리. */
.prose pre.highlight code[data-name]::before {
  content: attr(data-name);
  display: block;
  margin: -0.9rem -1.1rem 0.9rem;
  padding: 0.4rem 1.1rem;
  font-size: 0.75rem;
  color: var(--ink-3);
  background: var(--paper);
  border-bottom: 1px solid var(--rule);
  border-radius: var(--radius) var(--radius) 0 0;
}

/* ---------- benchmark bars ---------- */

/* 도구 식별은 행 라벨이, 수치는 막대 옆 텍스트가 운반한다. 색은 우리(악센트)와
   비교군(중립) 둘뿐이라 색이 단독으로 정보를 나르지 않는다. 막대 폭이 style
   속성이 아니라 SVG rect의 표현 속성인 이유: 인라인 style은 이 사이트가
   지켜 온 strict style-src CSP 가능성을 깨기 때문이다. */
.bench {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.45rem 0.8rem;
  align-items: center;
  margin: 0.8rem 0 1.8rem;
}
.bench .b-name {
  font-family: var(--mono);
  font-size: 0.8rem;
  color: var(--ink);
  text-align: right;
}
.bench .b-row { display: flex; align-items: center; gap: 0.6rem; min-width: 0; }
.bench svg { flex: 1; min-width: 0; height: 0.75rem; display: block; }
.bench rect { fill: var(--ink-3); opacity: 0.55; }
.bench rect.b-us { fill: var(--accent); opacity: 1; }
.bench .b-val {
  font-family: var(--mono);
  font-size: 0.78rem;
  color: var(--ink-2);
  white-space: nowrap;
}

/* ---------- tables ---------- */

/* `display: block`이었다. 넓은 표를 가로로 굴리려던 것인데, 그러면 표가 내부
   레이아웃을 잃고 내용 폭으로 쭈그러들어 본문의 40%만 쓰는 모양이 된다.
   우리 표는 짧은 텍스트 두세 열이라 그냥 감싸면 되고, 진짜 넓은 표가 생기면
   그때 감싸는 상자를 두는 게 맞다. */
.prose table {
  border-collapse: collapse;
  width: 100%;
  max-width: 100%;
  font-size: var(--s-1);
  margin: 0 0 1.3rem;
}
.prose th, .prose td {
  text-align: left;
  padding: 0.55rem 0.9rem 0.55rem 0;
  border-bottom: 1px solid var(--rule);
  vertical-align: top;
}
/* 마지막 열의 오른쪽 여백은 필요 없다 — 표의 오른쪽 끝이 이미 여백이다. */
.prose th:last-child, .prose td:last-child { padding-right: 0; }
/* 머리글과 본문 사이는 더 굵게. 어디까지가 라벨인지가 한눈에 보여야 한다. */
.prose thead th { border-bottom-color: var(--ink-3); }
.prose th {
  font-family: var(--mono);
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
  font-weight: 500;
}

/* ---------- admonitions (comrak alerts) ---------- */

.prose .markdown-alert {
  border-left: 2px solid var(--ink-3);
  padding: 0.1rem 0 0.1rem 1rem;
  margin: 0 0 1.3rem;
  color: var(--ink-2);
}
.prose .markdown-alert-title {
  font-family: var(--mono);
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin: 0 0 0.35rem;
}
.prose .markdown-alert > p:last-child { margin-bottom: 0; }

.prose blockquote {
  margin: 0 0 1.3rem;
  padding-left: 1rem;
  border-left: 2px solid var(--rule);
  color: var(--ink-2);
}

.prose hr { border: 0; border-top: 1px solid var(--rule); margin: 2.5rem 0; }

/* ---------- section index ---------- */

.children { list-style: none; margin: 0; padding: 0; }
.children li { border-top: 1px solid var(--rule); }
.children li:last-child { border-bottom: 1px solid var(--rule); }
.children a {
  display: block;
  padding: 0.9rem 0;
  text-decoration: none;
  color: var(--ink);
}
.children a:hover { color: var(--accent); }
.children .desc { display: block; color: var(--ink-3); font-size: var(--s-1); margin-top: 0.15rem; }

/* ---------- footer ---------- */

.colophon {
  border-top: 1px solid var(--rule);
  max-width: 84rem;
  margin: 0 auto;
  padding: 2.5rem var(--gutter) 3.5rem;
  font-size: var(--s-1);
}

/* 세 덩이. 브랜드 열이 넓고 링크 열이 좁은 건 왼쪽이 읽는 것이고 오른쪽이
   찾는 것이기 때문이다. */
/* 열 폭을 비율로 두면 넓은 화면에서 링크 열이 오른쪽 끝까지 밀려 서로 상관없는
   덩이처럼 보인다. 왼쪽부터 채우고 남는 공간은 오른쪽에 둔다. */
.colophon-grid {
  display: grid;
  grid-template-columns: minmax(0, 20rem) repeat(2, minmax(0, 9rem));
  justify-content: start;
  gap: clamp(1.5rem, 5vw, 4rem);
}

.colophon-mark {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--mono);
  font-size: var(--s0);
  font-weight: 600;
  letter-spacing: -0.03em;
  color: var(--ink-2);
  text-decoration: none;
}
.colophon-mark:hover { color: var(--ink); text-decoration: none; }

.colophon-brand img {
  width: 1.7rem;
  height: 1.7rem;
  filter: invert(1);
  opacity: 0.6;
}
:root[data-theme="light"] .colophon-brand img { filter: none; }

.colophon-brand p {
  margin: 0.6rem 0 0;
  max-width: 24rem;
  color: var(--ink-3);
  line-height: 1.6;
}

/* 열 제목은 사이드바 갈래 제목과 같은 처리다. 라벨은 사이트 어디서나 같은
   물건으로 보여야 한다. */
.colophon h2 {
  margin: 0 0 0.7rem;
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.colophon ul { list-style: none; margin: 0; padding: 0; }
.colophon li + li { margin-top: 0.4rem; }
.colophon a {
  color: var(--ink-2);
  text-decoration: none;
  transition: color var(--tr);
}
.colophon a:hover { color: var(--accent); text-decoration: underline; }

/* ---------- Korean ----------
   Three Latin devices do not survive contact with Hangul:

   letter-spacing pushes syllable blocks apart until a word stops reading as one
   word; text-transform does nothing at all; and a monospace family is the worst
   of them, because Hangul falls back to a proportional font while the *space*
   still comes from the mono face, so every gap between 어절 renders double
   width and the heading looks broken.

   Structure still reads through size, weight and colour, which need no help. */
html[lang="ko"] .title-block h1,
html[lang="ko"] .prose h2,
html[lang="ko"] .prose h3,
html[lang="ko"] .prose h4,
html[lang="ko"] .nav-group > summary,
html[lang="ko"] .colophon h2,
html[lang="ko"] .toc::before,
html[lang="ko"] .prose th,
html[lang="ko"] .crumbs,
html[lang="ko"] .search-crumb,
html[lang="ko"] .prose .markdown-alert-title {
  font-family: var(--sans);
  letter-spacing: -0.01em;
  text-transform: none;
}
html[lang="ko"] .title-block h1,
html[lang="ko"] .prose h2,
html[lang="ko"] .prose h3,
html[lang="ko"] .prose h4 {
  font-weight: 700;
}

/* ---------- pager ---------- */

.pager {
  display: flex;
  gap: 1rem;
  margin-top: 4rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--rule);
}

.pager a {
  flex: 1;
  display: block;
  padding: 0.85rem 1rem;
  border: 1px solid var(--rule);
  border-radius: 4px;
  color: inherit;
  text-decoration: none;
}
.pager a:hover { border-color: var(--accent); }

/* A single "next" sits on the right, where the reader is heading. */
.pager-next { text-align: right; }
.pager-next:only-child { margin-left: auto; flex: 0 1 auto; }

.pager span {
  display: block;
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 0.2rem;
}
.pager strong { font-weight: 600; }

html[lang="ko"] .pager span {
  font-family: var(--sans);
  letter-spacing: -0.01em;
  text-transform: none;
}

@media (max-width: 40rem) {
  .pager { flex-direction: column; }
  .pager-next { text-align: left; }
}

/* ---------- search palette ----------
   A <dialog>. Escape, the backdrop, the focus trap and returning focus to the
   trigger are all the element's own behaviour; none of it is written here. */

.search-dialog {
  border: none;
  background: none;
  padding: 0;
  margin: 0 auto;
  width: min(40rem, calc(100vw - 2rem));
  max-width: none;
  max-height: 100dvh;
  margin-top: 12vh;
}
.search-dialog::backdrop { background: rgb(0 0 0 / 0.55); }

.search-panel {
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 8px;
  box-shadow: 0 1.5rem 3rem rgb(0 0 0 / 0.35);
  overflow: hidden;
}

.search-panel input {
  width: 100%;
  font: var(--s1)/1.4 var(--sans);
  color: var(--ink);
  background: none;
  border: none;
  border-bottom: 1px solid var(--rule);
  padding: 1rem 1.15rem;
}
.search-panel input:focus { outline: none; }
.search-panel input::placeholder { color: var(--ink-3); }
/* The UA's clear button for type=search is a heavy glyph that sits at a
   different weight from everything else here. Escape already clears. */
.search-panel input::-webkit-search-cancel-button { display: none; }

.search-results {
  list-style: none;
  margin: 0;
  padding: 0.35rem;
  max-height: min(26rem, 55dvh);
  overflow-y: auto;
}
.search-results:empty { display: none; }

.search-results a {
  display: block;
  padding: 0.6rem 0.8rem;
  border-radius: 5px;
  color: inherit;
  text-decoration: none;
}
.search-results a[aria-selected] { background: var(--raised); }
.search-results a[aria-selected] .search-title { color: var(--accent); }

.search-crumb {
  display: block;
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.search-title {
  display: block;
  font-weight: 600;
  line-height: 1.35;
}
.search-snippet {
  display: block;
  font-size: var(--s-1);
  line-height: 1.5;
  color: var(--ink-2);
  /* Two lines is enough to show why a page matched. More turns the list into
     a wall and hides the results below it. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.search-results mark {
  background: none;
  color: var(--accent);
  font-weight: 600;
}

.search-foot {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  border-top: 1px solid var(--rule);
  padding: 0.5rem 1.15rem;
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--ink-3);
}

/* ---------- narrow screens ----------
   여기 규칙이 없어서 420px에서 마스트헤드가 무너졌다. 브랜드가 한 글자씩 세로로
   쪼개지고 GitHub도 마찬가지였다. 좁아지면 줄이는 게 아니라 **뺀다** — 갈래 내비는
   사이드바 서랍이 같은 일을 하고, GitHub는 콜로폰에 이미 있다. */

@media (max-width: 60rem) {
  .layout {
    grid-template-columns: minmax(0, 1fr);
    padding-top: 1.5rem;
  }

  /* 서랍이 된다. 열고 닫는 건 <details>가, 처음 닫는 건 ui.js가 한다. */
  .sidebar {
    position: static;
    /* 넓은 화면에서 경계선을 채우려고 준 높이를 되돌린다. 안 그러면 서랍이
       접혀 있어도 100vh를 차지해 본문이 화면 밖으로 밀린다. */
    height: auto;
    max-height: none;
    overflow: visible;
    border-right: none;
    border-bottom: 1px solid var(--rule);
    padding: 0 0 1rem;
    margin-bottom: 1.5rem;
  }
  .sidebar > summary {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    height: var(--control-h);
    padding: 0 0.6rem;
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    font-family: var(--mono);
    font-size: var(--s-1);
    color: var(--ink-2);
    cursor: pointer;
    list-style: none;
  }
  .sidebar > summary::-webkit-details-marker { display: none; }
  .sidebar > summary::before {
    content: "";
    width: 0.35rem;
    height: 0.35rem;
    border-right: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    transform: rotate(-45deg);
  }
  .sidebar[open] > summary::before { transform: rotate(45deg); }
  .sidebar[open] > nav { margin-top: 0.75rem; }

  /* 목차는 사이드바 서랍과 같은 말을 한 번 더 하는 셈이라 뺀다. */
  .toc { display: none; }

  .colophon-grid { grid-template-columns: minmax(0, 1fr); gap: 2rem; }

  /* 갈래 내비도 서랍에 있다. */
  .sections { display: none; }

  /* GitHub는 콜로폰에 있다. 검색은 라벨만 남기고 단축키 힌트를 뺀다 —
     터치 화면에는 누를 키가 없다. */
  .chip-wide { display: none; }
  .search-trigger { min-width: 0; }
  .search-trigger kbd { display: none; }
}

@media (max-width: 26rem) {
  /* 이보다 좁으면 워드마크까지 자리를 다툰다. 마크만 남긴다 — 로고가 곧 이름이다. */
  .brand span { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}
