/*
 * 사주 API 공개 사이트 — 한지·먹·주사(朱砂).
 *
 * 참조 사이트와 같은 내용을 다루되 인상은 달라야 한다. 쓰는 재료는 셋뿐이다.
 *   바탕은 한지(#f4efe4), 글자는 먹(#1f1b16), 강조는 인장의 주사(#9c2b21).
 * 오행 다섯 색은 데이터에만 쓰고 장식으로 쓰지 않는다 — 다섯 색을 장식에 풀면
 * 화면이 금세 촌스러워지고, 정작 오행을 표시할 때 의미가 죽는다.
 *
 * 폰트는 제목만 명조로 간다. 본문까지 명조로 두면 코드·표와 부딪혀 읽기 어렵다.
 */

:root {
  --paper:      #f4efe4;   /* 한지 */
  --paper-2:    #ece5d6;   /* 한 겹 접힌 자리 */
  --paper-3:    #e0d7c4;
  --ink:        #1f1b16;   /* 먹 */
  --ink-2:      #4a423a;
  /*
   * --ink-3 은 13.5px 작은 글씨(.dim·.small.dim)를 거의 전담한다. 본래 #7a6f62 였는데
   * 한지 위에서 4.28:1 이라 작은 글씨 기준(AA 4.5:1)에 못 미쳤다 — 이 사이트에서
   * 가장 많이 깔리는 색이라 그냥 둘 수 없다. 색조(r-g=11, g-b=13)는 그대로 두고
   * 명도만 한 칸 내려 --paper 5.11:1 · --paper-2 4.67:1 로 맞춘다.
   */
  --ink-3:      #6e6356;
  --cinnabar:   #9c2b21;   /* 주사 — 글자와 선 */
  --cinnabar-2: #c2402f;
  /*
   * 주사를 **면으로 칠할 때**(버튼)는 토큰을 따로 둔다.
   * 글자용 주사는 다크 모드에서 바탕이 어두운 만큼 밝아져야 하는데, 그 밝아진 주사를
   * 버튼 바탕으로 그대로 쓰면 위에 얹힌 흰 글자가 4.01:1 까지 떨어졌다(hover 는 3.16:1).
   * 쓰임이 정반대라 한 토큰으로는 둘 다 만족시킬 수 없어 갈랐다.
   */
  --cinnabar-fill:   #9c2b21;
  --cinnabar-fill-2: #c2402f;
  --on-cinnabar:     #fff;
  --celadon:    #46655d;   /* 청자 */
  --gold:       #9a7b33;
  --line:       #cdc2ac;
  --line-2:     #ded4c0;

  /*
   * 오행 — 데이터 표시 전용.
   * 지금 이 다섯 색을 쓰는 페이지는 없다(아래 .oh 뿐이고 .oh 를 붙인 마크업이 없다).
   * 오행을 화면에 그리는 날 여기서부터 쓰라고 남겨 둔다. 장식으로 풀지 않는다.
   */
  --o-mok: #3f6b4a;  --o-hwa: #a63a2a;  --o-to: #9a7b33;
  --o-geum: #6b6f75; --o-su: #2f4458;

  --serif: 'Nanum Myeongjo', 'Noto Serif KR', 'AppleMyungjo', 'Batang', serif;
  --sans: -apple-system, BlinkMacSystemFont, 'Apple SD Gothic Neo', 'Pretendard',
          'Malgun Gothic', 'Noto Sans KR', sans-serif;
  --mono: 'SF Mono', 'JetBrains Mono', 'D2Coding', ui-monospace, Menlo, monospace;

  --wrap: 1060px;
  --radius: 2px;      /* 각을 살린다 — 둥근 모서리는 이 인상과 맞지 않는다 */

  /*
   * 머리글 높이. 붙박이 목차의 top, 앵커 스크롤 여백, 현재 절 판정(layout.ts 의 96)이
   * 전부 이 값에서 나오는데 84·80·96 이라는 상수로 흩어져 있었다. 하나를 고치면
   * 나머지가 어긋난다. 좁은 화면(≤720px)에서는 머리글이 접혀 높이가 달라지지만
   * 붙박이 목차는 940px 이상에서만 걸리므로 그 구간에서만 정확하면 된다.
   */
  --head-h: 62px;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    --paper: #16130f; --paper-2: #1e1a15; --paper-3: #272119;
    --ink: #ece4d6; --ink-2: #c3b8a6; --ink-3: #8e8373;
    --cinnabar: #d05a48; --cinnabar-2: #e0705c;
    /* 면으로 칠하는 주사는 밝히지 않는다 — 흰 글자가 얹히기 때문이다.
       #b03c29 에서 흰 글자 5.96:1, 버튼 자체도 바탕과 3.11:1 로 테두리가 보인다. */
    --cinnabar-fill: #b03c29; --cinnabar-fill-2: #c24632;
    --celadon: #7fa79c; --gold: #c5a259;
    --line: #3a322a; --line-2: #2c261f;
    --o-mok: #7ba787; --o-hwa: #d97a67; --o-to: #c5a259;
    --o-geum: #a8adb5; --o-su: #7d9cb8;
  }
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

/* 목차를 누를 때마다 화면이 흐르는 것을 견디지 못하는 사람이 있다. 운영체제 설정을 따른다 */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

/*
 * 이 사이트가 무언가를 감추는 방법은 전부 hidden 속성이다(탭 패널, 대시보드의
 * 로그인 전/후, 용어집 검색 결과). 그런데 hidden 의 기본 display:none 은 클래스
 * 하나만 display 를 잡아도 진다 — .row 나 .grid 가 붙은 자리에 hidden 을 걸면
 * 그대로 보인다. 속성 쪽에 못을 박아 그 사고를 원천에서 막는다.
 * (이전에는 쓰이지 않는 .hidden 클래스가 그 자리를 대신하고 있었다)
 */
[hidden] { display: none !important; }

/*
 * 키보드로 도는 사람에게 지금 어디인지 보여 준다. 여기가 없으면 브라우저 기본
 * 파란 테를 쓰게 되는데, 한지 위에서 그 파랑만 홀로 튄다. :focus-visible 이라
 * 마우스로 누를 때는 나타나지 않는다.
 */
:focus-visible {
  outline: 2px solid var(--cinnabar);
  outline-offset: 2px;
  border-radius: var(--radius);
}
/* 칸 안쪽을 채우는 것들은 테를 안으로 넣어야 이웃을 밀지 않는다 */
:is(input, select, textarea):focus-visible { outline-offset: -1px; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 16px/1.75 var(--sans);
  letter-spacing: -0.003em;
  -webkit-font-smoothing: antialiased;
  /*
   * 한지 결. 이미지 없이 아주 옅은 사선 두 겹으로 만든다.
   * 외부 요청이 없어야 첫 화면이 빨리 뜨고, CSP 도 단순해진다.
   */
  background-image:
    repeating-linear-gradient(64deg,  transparent 0 3px, rgb(0 0 0 / 1.1%) 3px 4px),
    repeating-linear-gradient(-51deg, transparent 0 5px, rgb(0 0 0 / 0.8%) 5px 6px);
}

@media (prefers-color-scheme: dark) {
  /*
   * 토큰과 **같은 조건**을 건다. 여기만 :root 조건이 빠져 있어서, data-theme='light'
   * 를 세우면 색은 한지로 돌아오는데 결은 흰 선인 채로 남아 종이 결이 사라졌다.
   */
  :root:not([data-theme='light']) body { background-image:
    repeating-linear-gradient(64deg,  transparent 0 3px, rgb(255 255 255 / 1.4%) 3px 4px),
    repeating-linear-gradient(-51deg, transparent 0 5px, rgb(255 255 255 / 1%) 5px 6px); }
}

/* ── 뼈대 ───────────────────────────────────────────── */

.wrap { max-width: var(--wrap); margin: 0 auto; padding-inline: 24px; }

.site-head {
  border-bottom: 1px solid var(--line);
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: saturate(1.2) blur(8px);
  position: sticky; top: 0; z-index: 20;
}
.site-head .wrap { display: flex; align-items: center; gap: 28px; height: 62px; }

.brand { display: flex; align-items: center; gap: 10px; text-decoration: none; color: inherit; }
.brand b { font: 700 19px/1 var(--serif); letter-spacing: 0.02em; white-space: nowrap; }
.brand span { font-size: 11px; color: var(--ink-3); letter-spacing: 0.14em; white-space: nowrap; }

/*
 * 부제는 자리가 넉넉할 때만 보인다. 이름이 '수파사주 API' 로 길어지면서
 * 1000px 아래에서 머리글이 두 줄로 깨지고 마지막 메뉴가 밀려났다.
 */
@media (max-width: 1000px) { .brand > span:not(.mark) { display: none; } }

/*
 * 표식은 .mark(아래) 하나다. 예전에는 붉은 사각에 글자를 앉힌 .seal 을 그렸는데,
 * supaSAJU 와 같은 아이콘을 쓰기로 하면서(9d449a2) 어느 페이지도 .seal 을 부르지
 * 않게 되었다. 그리지 않는 규칙은 지운다 — 남겨 두면 다음 사람이 둘 중 무엇이
 * 이 사이트의 표식인지 헷갈린다.
 */

.nav { display: flex; gap: 22px; margin-left: auto; align-items: center; flex-wrap: wrap; }
.nav a { color: var(--ink-2); text-decoration: none; font-size: 14px; white-space: nowrap; }
.nav a:hover, .nav a[aria-current] { color: var(--cinnabar); }

/* ── 활자 ───────────────────────────────────────────── */

h1, h2, h3, h4 { font-family: var(--serif); font-weight: 700; letter-spacing: -0.01em; }
h1 { font-size: clamp(30px, 4.6vw, 46px); line-height: 1.28; margin: 0 0 14px; }
h2 { font-size: 25px; line-height: 1.4; margin: 56px 0 16px; }
h3 { font-size: 19px; margin: 36px 0 10px; }
p { margin: 0 0 16px; }
a { color: var(--cinnabar); text-underline-offset: 3px; }

.lede { font-size: 18px; line-height: 1.8; color: var(--ink-2); }
.dim { color: var(--ink-3); }
.small { font-size: 13.5px; }
.accent { color: var(--cinnabar); }
.nowrap { white-space: nowrap; }

/*
 * .dim 은 흐린 글씨(--ink-3), .note 는 본문보다 한 톤 여린 글씨(--ink-2).
 * 상자 안 설명문이 거의 .small.note 꼴인데, 생성기에 style="color:var(--ink-2)"
 * 로 스무 군데 손으로 적혀 있었다. .dim 과 마찬가지로 **색만** 맡고 크기는
 * .small 에 맡긴다 — 둘을 한 클래스에 묶으면 크기만 다른 자리에서 또 갈라진다.
 */
.note { color: var(--ink-2); }

/* 앞 문단에 바짝 잇는다. 한 말의 이어짐이라 문단 사이를 다 벌리지 않는 자리 */
.tuck { margin-top: -8px; }

/* 보이지는 않지만 낭독기에는 읽히는 글 — 입력칸 이름표처럼 눈으로는 없어도 되는 것 */
.a11y-only {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/* 입력칸 아래 붙는 한 줄 도움말. 값이 6px·8px 로 갈려 있던 것을 하나로 모은다 */
.hint { margin: 6px 0 0; font-size: 13.5px; color: var(--ink-3); }

/* 글줄 길이 잡기. 같은 자리(h1 밑 도입 문단)에 720·760 두 값이 쓰이고 있었다 */
.hold { max-width: 760px; }

/* 절(節) 표시 — 제목 위 작은 붉은 머리글 */
.eyebrow {
  font: 600 11.5px/1 var(--sans); letter-spacing: 0.2em;
  color: var(--cinnabar); text-transform: uppercase;
  margin: 0 0 12px; display: flex; align-items: center; gap: 9px;
}
.eyebrow::before { content: ''; width: 18px; height: 1px; background: var(--cinnabar); }
/* 절 표시 바로 밑 제목은 h2 의 56px 윗여백이 필요 없다 — 이미 절이 시작된 자리다 */
.eyebrow + :is(h1, h2) { margin-top: 0; }

/* ── 상자 ───────────────────────────────────────────── */

.panel {
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 22px 24px;
}
/*
 * 상자 안 첫 줄과 마지막 줄의 바깥 여백은 상자가 이미 padding 으로 잡고 있다.
 * 생성기마다 style="margin-top:0" / style="margin:0" 을 손으로 붙이고 있었고
 * (열일곱 군데), 붙이는 것을 잊은 자리는 위아래 여백이 저 혼자 두꺼웠다.
 */
.panel > :first-child { margin-top: 0; }
.panel > :last-child { margin-bottom: 0; }

/* 가운데로 모은 상자 — 마지막 권유(CTA) 자리 */
.panel.center { text-align: center; padding: 40px 24px; }
/* 표식 바로 밑에 오는 제목은 h2 의 56px 윗여백을 쓰지 않는다 — 표식과 한 덩이다 */
.mark.lg + h2 { margin: 16px 0 8px; }
/* 감수 표기 상자. 앞뒤 절과 떨어뜨린다 (REVIEWED 가 채워질 때만 나온다) */
.panel.reviewed { margin: 18px 0; }

/*
 * 본문 흐름에 홀로 놓인 상자는 표(.tablewrap)·코드(pre)와 같은 18px 아랫여백을 갖는다.
 * 격자 안 상자에는 걸지 않는다 — 거기서는 격자의 gap 이 간격을 맡고 있어서,
 * 상자에 여백을 더하면 칸 사이만 두 겹으로 벌어진다.
 */
main > .panel { margin-bottom: 18px; }

/* 왼쪽에 주사 괘선 하나 — 인용이나 강조 단락에 */
.rule-left { border-left: 3px solid var(--cinnabar); padding-left: 18px; }

/*
 * 격자는 720px 을 넘어서면서부터 칸을 나눈다. 이 값이 .wrap 의 좁은 화면
 * 기준(720px)보다 한 칸 위에 있어야, 여백이 줄어드는 폭과 칸이 갈라지는 폭이
 * 겹치지 않는다 — 두 변화가 같은 지점에서 일어나면 그 한 픽셀에서 화면이 출렁인다.
 */
.grid { display: grid; gap: 18px; }
/*
 * 그리드 칸은 기본 min-width 가 auto 라, 안에 든 pre 의 가장 긴 줄이 칸을 밀어
 * 격자 전체가 화면 밖으로 삐져나간다. overflow-x:auto 를 pre 에 걸어도 소용없다 —
 * 칸이 먼저 넓어지기 때문이다. 0 으로 눌러야 pre 가 제 안에서 스크롤한다.
 */
.grid > * { min-width: 0; }
@media (min-width: 760px) {
  /* c4 는 어느 페이지도 쓰지 않아 지웠다. 필요해지면 이 줄 옆에 다시 세우면 된다 */
  .grid.c2 { grid-template-columns: 1fr 1fr; }
  .grid.c3 { grid-template-columns: repeat(3, 1fr); }
}

/* 도입 문단 다음의 격자·격자 다음의 문단. 22·30·32 와 14·18 로 갈려 있던 자리다 */
.lede + .grid { margin-top: 32px; }
.grid + p { margin-top: 16px; }

.btn {
  display: inline-block; padding: 11px 22px;
  background: var(--cinnabar-fill); color: var(--on-cinnabar); text-decoration: none;
  border: 1px solid var(--cinnabar-fill); border-radius: var(--radius);
  font-size: 15px; font-weight: 600;
}
.btn:hover { background: var(--cinnabar-fill-2); border-color: var(--cinnabar-fill-2); }
.btn.ghost { background: transparent; color: var(--ink); border-color: var(--line); }
.btn.ghost:hover { border-color: var(--ink-3); background: var(--paper-3); }

/*
 * 버튼 두엇을 나란히 세우는 자리. 좁아지면 접힌다 — margin-left 로는 접히지 않는다.
 * 아래 여백은 남긴다. 0 으로 두었더니 히어로에서 버튼 바로 밑 한 줄이 들러붙었다.
 * 상자의 마지막 줄일 때는 .panel > :last-child 가 다시 0 으로 눌러 준다.
 */
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 24px 0 16px; }
.center .actions { justify-content: center; }

.tag {
  display: inline-block; padding: 2px 8px; border-radius: var(--radius);
  border: 1px solid var(--line); background: var(--paper-3);
  font: 600 11.5px/1.6 var(--sans); color: var(--ink-2);
  vertical-align: 2px;
}
.tag.free { border-color: var(--celadon); color: var(--celadon); background: transparent; }
.tag.pro  { border-color: var(--cinnabar); color: var(--cinnabar); background: transparent; }

/* ── 코드 ───────────────────────────────────────────── */

code, kbd { font-family: var(--mono); font-size: 0.895em; }
:not(pre) > code {
  background: var(--paper-3); border: 1px solid var(--line-2);
  border-radius: var(--radius); padding: 1px 5px; color: var(--ink);
}
pre {
  margin: 0 0 16px; padding: 16px 18px; overflow-x: auto;
  background: var(--paper-2); border: 1px solid var(--line);
  border-radius: var(--radius); font-size: 13px; line-height: 1.7;
}
pre code { background: none; border: 0; padding: 0; }

/* 코드 블록 묶음 — 언어 탭 */
.codeset { margin: 0 0 20px; }
.tabs { display: flex; gap: 0; border-bottom: 1px solid var(--line); margin-bottom: -1px; }
.tabs button {
  appearance: none; border: 1px solid transparent; border-bottom: 0;
  background: none; cursor: pointer; padding: 7px 16px;
  font: 600 13px/1.5 var(--sans); color: var(--ink-3);
  border-radius: var(--radius) var(--radius) 0 0;
}
.tabs button[aria-selected='true'] {
  color: var(--cinnabar); background: var(--paper-2);
  border-color: var(--line); border-bottom-color: var(--paper-2);
}
.codeset pre { border-top-left-radius: 0; }

/* ── 표 ─────────────────────────────────────────────── */

.tablewrap { overflow-x: auto; margin: 0 0 18px; }
table { border-collapse: collapse; width: 100%; font-size: 14px; }
th, td {
  text-align: left; padding: 9px 12px;
  border-bottom: 1px solid var(--line-2); vertical-align: top;
}
th { font-weight: 700; color: var(--ink-2); border-bottom-color: var(--line); white-space: nowrap; }
td code { white-space: nowrap; }
tbody tr:hover { background: var(--paper-2); }
/*
 * 숫자 칸.
 *
 * th 는 이미 블록 컨테이너라 text-align 이 그대로 먹는다. 하지만 td 안의
 * <span class="num"> 은 **인라인이라 자기 자신을 옮기지 못해** text-align 이
 * 아무 일도 하지 않고, 자릿수가 다른 금액이 왼쪽에 들쭉날쭉 선다. 그래서
 * span 만 블록으로 세워 칸을 채우게 한다.
 *
 * ⚠️ display:block 을 .num 전체에 걸면 안 된다. th 가 블록이 되는 순간 표
 * 서식에서 빠져나가 머리글이 세로로 무너진다(실제로 그랬다).
 */
.num { text-align: right; font-variant-numeric: tabular-nums; }
span.num { display: block; }

/* ── 페이지 뼈대 ────────────────────────────────────── */

/*
 * 세로 여백의 척도.
 *
 * 절 사이 여백이 34·40·42·44·46·52·70·74·90 처럼 제각각이었다. 서로 다른 페이지를
 * 나란히 놓으면 같은 자리가 다르게 숨쉰다. **32px 이상은 4의 배수만 쓴다**로 정하고
 * 큰 값만 맞췄다. 32px 아래(활자 사이 간격)는 활자 크기에 매인 값이라 건드리지 않는다 —
 * 거기까지 척도로 눌렀다가는 읽는 맛이 상한다.
 *
 * .page 는 목차 없는 단칸 페이지, .doc 는 목차가 붙는 두 칸 페이지, .band 는
 * 랜딩처럼 절이 여러 겹 쌓이는 페이지의 한 겹이다.
 */
.page { padding-block: 52px 80px; }

.band { padding-block: 44px; }
.band.lead { padding-block: 36px; }       /* 앞 절에 바로 이어 붙는 겹 */
.band.last { padding-block: 36px 72px; }  /* 마지막 겹 — 바닥글 앞에서 한 번 쉰다 */

.doc { display: block; padding-block: 36px 88px; }
@media (min-width: 940px) {
  .doc { display: grid; grid-template-columns: 218px minmax(0, 1fr); gap: 48px; align-items: start; }
}
/*
 * 붙박이(sticky)는 **격자가 살아 있을 때만** 건다. 본문 옆 칸에 있을 때만 말이
 * 되는 동작이라, 한 줄로 떨어지는 폭에서 그대로 두면 목차가 본문 위를 덮으며
 * 따라 내려온다 — 721~939px 구간에서 실제로 그랬다.
 */
.toc { font-size: 14px; }
/* 붙박이 목차는 머리글 바로 아래 22px 에 선다 — 머리글 높이는 --head-h 하나에서 온다 */
@media (min-width: 940px) { .toc { position: sticky; top: calc(var(--head-h) + 22px); } }
.toc h4 {
  font: 600 11.5px/1 var(--sans); letter-spacing: 0.16em; color: var(--ink-3);
  text-transform: uppercase; margin: 0 0 10px;
}
.toc ul { list-style: none; margin: 0 0 22px; padding: 0; }
.toc li { margin: 0; }
.toc a {
  display: block; padding: 4px 0 4px 12px; color: var(--ink-2);
  text-decoration: none; border-left: 2px solid var(--line-2);
}
.toc a:hover { color: var(--cinnabar); border-left-color: var(--cinnabar); }
.toc a[aria-current] { color: var(--cinnabar); border-left-color: var(--cinnabar); font-weight: 600; }

.doc main > *:first-child { margin-top: 0; }

/* 문서 안 제목에 앵커 여백 — sticky 헤더에 가리지 않게 */
main :is(h2, h3)[id] { scroll-margin-top: calc(var(--head-h) + 18px); }

/* ── 토픽 카드 ──────────────────────────────────────── */

.topic-card {
  display: block; text-decoration: none; color: inherit;
  background: var(--paper-2); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 18px 20px;
}
.topic-card:hover { border-color: var(--cinnabar); }
.topic-card h3 { margin: 0 0 6px; font-size: 17px; }
.topic-card p { margin: 0; font-size: 13.5px; color: var(--ink-3); line-height: 1.65; }
.topic-card .path { font: 12px/1 var(--mono); color: var(--celadon); margin-top: 10px; display: block; }

/* ── 요금제 ─────────────────────────────────────────── */

.plan { display: flex; flex-direction: column; }
/* 요금제 이름 — 제목 태그를 쓰지 않는다. 카드 목록의 h3 가 문서 차례를 어지럽힌다 */
.plan .name { font: 700 17px/1.4 var(--serif); }
.plan .price { font: 700 27px/1.2 var(--serif); margin: 6px 0 2px; }
.plan .price small { font: 400 13px/1 var(--sans); color: var(--ink-3); }
.plan ul { list-style: none; margin: 14px 0 0; padding: 0; font-size: 14px; }
.plan li { padding: 5px 0 5px 17px; position: relative; color: var(--ink-2); }
.plan li::before {
  content: ''; position: absolute; left: 0; top: 13px;
  width: 5px; height: 5px; background: var(--cinnabar);
}
.plan.featured { border-color: var(--cinnabar); box-shadow: 0 0 0 1px var(--cinnabar); }

/*
 * 기간 탭.
 *
 * 화면 전체에 하나뿐인 선택이라 카드 위로 올린다. 탭을 바꾸면 카드가 전부 그
 * 기간의 값으로 바뀐다 — 그래야 같은 기간에서 플랜끼리 견줄 수 있다.
 *
 * 모양은 탭인데 노릇은 라디오다(패널을 갈아 끼우는 것이 아니라 값을 고른다).
 * 그래서 role 은 radiogroup 이고 상태는 aria-checked 가 진다.
 *
 * 고르지 않은 칸에도 테두리를 준다. 글자만 띄워 두었더니 누를 수 있는 것으로
 * 보이지 않고, 고른 칸 하나만 붉은 덩어리로 떠 있었다.
 */
.termtabs {
  display: flex; flex-wrap: wrap; gap: 6px;
  margin: 0 auto 20px; max-width: 620px;
}
.termtabs button {
  flex: 1 1 130px; padding: 9px 12px; font: 600 14px/1.3 var(--sans); white-space: nowrap;
  background: var(--paper-2); color: var(--ink-2); border: 1px solid var(--line);
  border-radius: var(--radius);
  display: flex; align-items: center; justify-content: center; gap: 6px;
}
.termtabs button:hover:not([aria-checked="true"]) { background: var(--paper-3); color: var(--ink); border-color: var(--ink-3); }
.termtabs button[aria-checked="true"] {
  background: var(--cinnabar-fill); border-color: var(--cinnabar-fill); color: var(--on-cinnabar);
}
/* 할인 폭. 고르지 않은 칸에서도 읽혀야 하므로 색이 아니라 자리로 구분한다 */
.termtabs .off { font-size: 12px; font-weight: 700; opacity: 0.85; }

/* 기간이 바뀌었음을 낭독기에만 알린다 — 눈으로는 값이 바뀌는 것이 보인다 */
.sr-live {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* 이름과 '추천' 을 한 줄에 */
.buycard .planhead { display: flex; align-items: baseline; gap: 8px; }
.buycard .pick {
  margin-left: auto; font: 700 11px/1 var(--sans); letter-spacing: 0.06em;
  color: var(--cinnabar); border: 1px solid var(--cinnabar); border-radius: 2px; padding: 4px 7px;
}

/*
 * 구매 단추는 카드 바닥에 붙인다 — 카드 키가 달라도 단추 줄은 나란하다.
 * 넷 다 붉게 칠했더니 붉은 덩어리 넷이 화면을 눌러, 어디를 보아야 할지 알 수
 * 없었다. 추천 하나만 채우고 나머지는 테두리만 둔다.
 */
.buycard .buyline { margin-top: auto; padding-top: 20px; }
.buycard .buy { width: 100%; padding: 12px 18px; font-size: 15px; }
.buycard .perline { margin: 0 0 2px; min-height: 1.4em; }
.buycard .price { margin-top: 12px; }
.buycard .price small { font: 400 13px/1 var(--sans); color: var(--ink-3); margin-left: 3px; }

/* ── 히어로 장식 ────────────────────────────────────── */

/*
 * 천간 열 글자를 세로로 아주 옅게 흘린다. 족자의 글씨 자리다.
 * 내용이 아니라 결이라 aria-hidden 으로 두고, 좁은 화면에서는 걷는다.
 */
/*
 * 히어로는 아래 절들보다 좁게 잡는다(840px). 첫 문단은 글줄이 길면 읽다가 놓친다.
 * .wrap 의 1060px 을 덮어쓰는 것이라 이 규칙이 .wrap 보다 **아래**에 있어야 한다.
 * 생성기에 style="padding-block:74px 20px;max-width:840px" 로 박혀 있던 값이다.
 */
.hero { position: relative; max-width: 840px; padding-block: 72px 20px; }
.hero-glyphs {
  position: absolute; top: -18px; right: 0; pointer-events: none; user-select: none;
  font: 400 30px/1.42 var(--serif);
  color: var(--ink); opacity: 0.055;
  writing-mode: vertical-rl; letter-spacing: 0.3em;
  max-height: 340px; overflow: hidden;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .hero-glyphs { opacity: 0.085; }
}
/* 히어로 문단이 840px 이라, 900px 아래에서는 글씨 자리가 본문과 겹치기 시작한다 */
@media (max-width: 900px) { .hero-glyphs { display: none; } }

/* 절을 가르는 붉은 마름모 — hr 대신 쓰는 가벼운 매듭 */
.knot { display: flex; align-items: center; gap: 12px; margin: 52px 0; color: var(--line); }
.knot::before, .knot::after { content: ''; height: 1px; background: currentColor; flex: 1; }
.knot span {
  width: 7px; height: 7px; background: var(--cinnabar);
  transform: rotate(45deg); flex: none;
}

/* ── 오행 색점 ──────────────────────────────────────── */

/* 아직 이 표식을 붙인 화면이 없다. 오행을 그리게 되면 여기가 그 자리다(위 --o-* 주석) */
.oh { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
.oh::before { content: ''; width: 8px; height: 8px; border-radius: 50%; background: currentColor; }
.oh.mok { color: var(--o-mok); } .oh.hwa { color: var(--o-hwa); }
.oh.to { color: var(--o-to); }  .oh.geum { color: var(--o-geum); }
.oh.su { color: var(--o-su); }

/* ── 바닥 ───────────────────────────────────────────── */

.site-foot {
  border-top: 1px solid var(--line); margin-top: 80px;
  padding-block: 36px 48px; font-size: 13.5px; color: var(--ink-3);
}
.site-foot .wrap { display: flex; gap: 32px; flex-wrap: wrap; justify-content: space-between; }
/* 바닥의 이름은 머리글과 같은 명조로. 생성기에 style 로 박혀 있던 것을 옮겼다 */
.site-foot b { display: block; font-family: var(--serif); color: var(--ink-2); }
.site-foot .foot-tag { margin-top: 4px; }
.site-foot a { color: var(--ink-2); text-decoration: none; }
.site-foot a:hover { color: var(--cinnabar); }
.site-foot nav { display: flex; gap: 18px; flex-wrap: wrap; }

hr { border: 0; border-top: 1px solid var(--line); margin: 44px 0; }

/*
 * 인쇄할 일은 드물지만, 문서 사이트라 한 번은 눌린다.
 * 다크 모드로 보던 화면을 그대로 누르면 상자·표·코드가 전부 검게 칠해져 나왔다 —
 * 종이에는 검정 잉크를 들이붓는 셈이다. 토큰을 한지 쪽으로 되돌려 놓고 찍는다.
 */
@media print {
  :root, :root:not([data-theme='light']) {
    --paper: #fff; --paper-2: #fff; --paper-3: #fff;
    --ink: #000; --ink-2: #222; --ink-3: #555;
    --line: #999; --line-2: #bbb;
  }
  .site-head, .toc, .site-foot { display: none; }
  body { background: #fff; color: #000; background-image: none; }
  .doc { display: block; }
  /* 종이에서는 접힌 곳도 펴서 보여 준다 */
  details { border: 0; padding: 0; }
  details > :not(summary) { display: block; }
}

/* ── 해설 문장 ──────────────────────────────────────── */

/*
 * 엔진이 내는 해설은 코드가 아니라 문장이다. pre 에 넣으면 줄이 안 접혀
 * 가로로 스크롤되고, 읽히지 않는다. 문장은 문장으로 보여 준다.
 */
.says { list-style: none; margin: 0 0 16px; padding: 0; }
.says li {
  border-left: 2px solid var(--line);
  padding: 0 0 0 14px; margin: 0 0 12px;
  font-size: 14.5px; line-height: 1.72; color: var(--ink-2);
}
.says li:last-child { margin-bottom: 0; }
.says .where {
  display: block; font: 11.5px/1.5 var(--mono);
  color: var(--ink-3); margin-bottom: 3px;
  overflow-wrap: anywhere;
}
.says.src li { border-left-color: var(--cinnabar); }

/* 용어집 짝 */
.terms { list-style: none; margin: 0; padding: 0; font-size: 14.5px; }
.terms li { margin: 0 0 11px; line-height: 1.7; color: var(--ink-2); }
.terms b { color: var(--ink); }

/* 긴 예시는 접어 둔다. 문서를 훑는 사람이 스크롤에 묻히지 않게 */
details {
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--paper-2); padding: 0 16px; margin: 0 0 18px;
}
details[open] { padding-bottom: 4px; }
summary {
  cursor: pointer; padding: 11px 0; font-size: 14px;
  font-weight: 600; color: var(--ink-2); list-style-position: inside;
}
summary:hover { color: var(--cinnabar); }
details pre { background: var(--paper); }

/* 용어집 초성 머리 — 표 바로 위에 붙이므로 여백을 줄인다 */
h2.cho { margin: 36px 0 8px; font-size: 21px; color: var(--cinnabar); }
h2.cho:first-of-type { margin-top: 20px; }

/* ── 좁은 화면 ──────────────────────────────────────── */

/* 목차가 한 줄로 떨어지는 폭에서는 가로 띠로. 세로로 두면 링크 스무 개가 본문보다 먼저 온다 */
@media (max-width: 939px) {
  .toc { margin: 0 0 26px; }
  .toc h4 { margin: 0 0 7px; }
  .toc ul {
    display: flex; gap: 7px; margin: 0 0 14px;
    overflow-x: auto; scrollbar-width: none; padding-bottom: 2px;
  }
  .toc ul::-webkit-scrollbar { display: none; }
  .toc a {
    border-left: 0; border: 1px solid var(--line-2);
    border-radius: var(--radius); padding: 5px 11px;
    white-space: nowrap; background: var(--paper-2); font-size: 13px;
  }
  .toc a[aria-current] { border-color: var(--cinnabar); background: var(--paper-3); }
}

@media (max-width: 720px) {
  .wrap { padding-inline: 18px; }

  /*
   * 머리글은 높이를 고정하지 않는다. 62px 에 묶어 두면 내비게이션이 두 줄로
   * 접힐 때 뒤엣것이 잘려 나간다 — 문서와 엔드포인트 링크가 사라졌었다.
   */
  .site-head .wrap { height: auto; padding-block: 10px; gap: 10px; flex-wrap: wrap; }
  .brand { gap: 8px; }
  .brand b { white-space: nowrap; font-size: 17px; }
  .nav {
    width: 100%; margin-left: 0; gap: 16px; overflow-x: auto;
    scrollbar-width: none; -webkit-overflow-scrolling: touch;
  }
  .nav::-webkit-scrollbar { display: none; }
  .nav a { font-size: 13.5px; }

  h1 { font-size: 29px; }
  h2 { font-size: 22px; margin-top: 44px; }
  .lede { font-size: 16.5px; }
  pre { font-size: 12px; padding: 13px 14px; }
  .panel { padding: 18px 16px; }
  /*
   * 세로 여백은 페이지 종류와 상관없이 같이 조인다. 목차 페이지(.doc)만 조이고
   * 랜딩·요금제(.page·.band)를 그대로 두었더니, 좁은 화면에서 문서는 촘촘한데
   * 랜딩만 혼자 헐렁했다.
   */
  .doc { padding-block: 26px 64px; }
  .page { padding-block: 36px 64px; }
  .band { padding-block: 32px; }
  .band.lead { padding-block: 24px; }
  .band.last { padding-block: 24px 56px; }
  .panel.center { padding: 28px 18px; }
  .site-foot .wrap { flex-direction: column; gap: 18px; }
}

/* ── 대시보드 ───────────────────────────────────────── */

.dash { padding-block: 36px 80px; }
.dash section { margin-bottom: 40px; }
.dash :is(h1, h2) { margin-top: 0; font-size: 22px; }
/*
 * 대시보드에도 h1 이 하나 있어야 한다. 예전에는 페이지 제목이 h2 였고 h1 이
 * 아예 없어서, 화면 낭독기로 읽으면 이 페이지만 제목 없이 시작했다. 크기는
 * 그대로 26px 이라 보이는 것은 달라지지 않는다.
 */
.dash h1 { font-size: 26px; line-height: 1.4; }
/* 절 제목 옆에 붙는 상자 안 소제목은 한 단 작게 */
.dash .panel h2 { font-size: 20px; }

.sechead { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
.sechead :is(h1, h2) { margin: 0; }
.sechead .dim { font-size: 13.5px; }
/* 줄 오른쪽 끝으로 미는 것(로그아웃 단추) */
.sechead .push { margin-left: auto; }
/* 절 안에서 이어지는 상자 사이 간격. 16px·14px 로 갈려 있던 것을 하나로 */
.dash section > .panel, #newKey { margin-top: 16px; }

label { display: block; font-size: 13px; font-weight: 600; color: var(--ink-2); margin: 0 0 5px; }
input[type='email'], input[type='password'], input[type='text'], input[type='url'], select {
  width: 100%; padding: 9px 12px; font: 15px var(--sans);
  background: var(--paper); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--radius);
}
/*
 * :focus 가 아니라 :focus-visible 은 위 공통 규칙이 맡는다. 입력칸은 마우스로
 * 눌렀을 때도 테가 보여야 어디에 쓰고 있는지 알 수 있어 :focus 를 따로 둔다.
 */
input:focus, select:focus { outline: 2px solid var(--cinnabar); outline-offset: -1px; }
/* 라벨 안에 끼는 부연은 라벨의 굵기를 따라가지 않는다 */
label .dim { font-weight: 400; }

/* 용어집 검색칸. 페이지에 style 로 열두 줄이 박혀 있었고 --radius 도 2px 로 손으로 적혀 있었다 */
.search {
  width: 100%; max-width: 340px; padding: 9px 12px;
  font: 15px var(--sans); background: var(--paper-2); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--radius);
}

.field { margin-bottom: 14px; }
.row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
/* 라벨이 얹힌 칸과 버튼을 나란히 둘 때 — 버튼이 입력칸 밑선에 맞아야 한다 */
.row.baseline { align-items: flex-end; }
/* 표 칸 안 잔 버튼들처럼 바짝 붙어야 하는 줄 */
.row.tight { gap: 4px; }
/* 위에 붙은 목록과 띄워야 하는 줄 */
.row.spaced { margin-top: 10px; }
/* 줄에서 남는 자리를 먹는 칸. 180·200 두 값이 쓰이고 있었다 */
.row .grow { flex: 1; min-width: 180px; }

button {
  font: 600 14px/1 var(--sans); padding: 10px 18px; cursor: pointer;
  background: var(--cinnabar-fill); color: var(--on-cinnabar);
  border: 1px solid var(--cinnabar-fill); border-radius: var(--radius);
}
button:hover:not(:disabled) { background: var(--cinnabar-fill-2); border-color: var(--cinnabar-fill-2); }
button:disabled { opacity: 0.5; cursor: default; }
button.ghost { background: transparent; color: var(--ink); border-color: var(--line); }
button.ghost:hover:not(:disabled) { background: var(--paper-3); border-color: var(--ink-3); }
button.link {
  background: none; border: 0; padding: 2px 4px; color: var(--cinnabar);
  text-decoration: underline; text-underline-offset: 3px; font-weight: 400;
}
button.link:hover:not(:disabled) { background: none; color: var(--cinnabar-2); }

/* 알림 — 오류는 붉게, 경고는 금빛, 완료는 청자 */
.msg {
  padding: 10px 14px; border-radius: var(--radius); font-size: 14px;
  border-left: 3px solid var(--line); background: var(--paper-2); margin: 12px 0 0;
}
.msg.err  { border-left-color: var(--cinnabar); }
.msg.ok   { border-left-color: var(--celadon); }
.msg.warn { border-left-color: var(--gold); }

.tag.revoked { border-color: var(--ink-3); color: var(--ink-3); }
.tag.active  { border-color: var(--celadon); color: var(--celadon); background: transparent; }

/* 사용량 막대 — 라이브러리 없이 SVG 하나로 */
.chart { width: 100%; height: 150px; display: block; }
.chart .bar { fill: var(--cinnabar); }
.chart .bar.err { fill: var(--gold); }
.chart .axis { stroke: var(--line); stroke-width: 1; }
.chart text { fill: var(--ink-3); font: 10px var(--sans); }

.stat { display: flex; gap: 28px; flex-wrap: wrap; margin-bottom: 16px; }
.stat > div { min-width: 92px; }
.stat b { display: block; font: 700 23px/1.2 var(--serif); color: var(--ink); }
.stat span { font-size: 12.5px; color: var(--ink-3); }

/* 새 키 — 한 번만 보여 주는 값이라 눈에 띄어야 한다 */
/*
 * 방금 발급한 키 한 줄.
 *
 * 이 화면을 벗어나면 키 원문은 어디에도 없다. 그래서 복사가 전부다 — 키를 눌러도
 * 복사되고, 복사 단추는 **키 오른쪽 끝**에 붙여 눈이 옮겨 갈 자리를 줄인다.
 */
.keyline { display: flex; align-items: stretch; gap: 8px; margin: 12px 0 0; }
.keyline pre { flex: 1; margin: 0; cursor: pointer; min-width: 0; }
.keyline pre:hover { border-color: var(--cinnabar-2); }
.keyline pre:focus-visible { outline: 2px solid var(--cinnabar); outline-offset: 2px; }
.keyline button { flex: none; align-self: center; white-space: nowrap; }

#newKey pre { border-color: var(--cinnabar); background: var(--paper); user-select: all; }

.keyrow-detail { background: var(--paper-2); }
.keyrow-detail td { padding: 14px 12px; }

/* 용어집 — 용어와 영문명은 접히지 않게. '건록격' 이 두 줄로 갈라지면 읽기 나쁘다 */
table.gl td:nth-child(1), table.gl td:nth-child(2) { white-space: nowrap; }
table.gl td:nth-child(2) { color: var(--ink-3); }
@media (max-width: 560px) { table.gl td:nth-child(2) { display: none; } }

/*
 * 앱 표식 — supaSAJU 와 같은 아이콘. 배경이 짙은 초록이라 종이 위에서 도장처럼 앉는다.
 * 테는 먹에서 뽑는다. 검정으로 박아 두었더니 다크 모드에서는 어두운 바탕에 묻혀
 * 아무것도 두르지 않은 것과 같았다.
 */
.mark {
  display: block; flex: none; border-radius: var(--radius);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--ink) 12%, transparent);
}
.mark.lg { width: 60px; height: 60px; margin: 0 auto; }
