/* 공통 부품(docs/ui-principles.md). 모양은 여기서만 정한다. 화면 CSS는 배치만 정하고 이 부품 모양을 덮어쓰지 않는다.
   마크업은 web/js/lib/ui/*.js 렌더 함수가 만든다. 견본: web/ui-kit.html. 값은 tokens.css의 --fs-*·--ctl-*·--r-*·--sp-* 이름만 쓴다.
   선택 상태는 속성으로 그린다: 하위 메뉴 aria-current, 화면 안 탭 aria-selected, 세그먼트·칩 aria-pressed. */

/* 화면에서만 숨기는 글자(읽기 프로그램은 읽는다). 숨김 클래스는 이것 하나다. */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}

/* ---------- 화면 머리: pageHead() ----------
   --doc 읽는 화면: 출처 줄 · 큰 제목 · 설명 두 줄 이하
   --tool 조작 화면: 작은 제목과 한 줄 설명을 PC는 한 줄에, 폰은 두 줄 이하로. 오른쪽에 동작 */
.ui-page-head{display:flex;flex-wrap:wrap;align-items:baseline;gap:var(--sp-1) var(--sp-3);margin:0 0 var(--sp-4);padding-bottom:var(--sp-3)}
.ui-page-head>h1{margin:0;font-weight:700;letter-spacing:-.02em;line-height:1.25;color:var(--ink)}
.ui-page-eyebrow{flex-basis:100%;margin:0;font-size:var(--fs-caption);font-weight:700;line-height:1.4;color:var(--muted)}
.ui-page-lede{margin:0;color:var(--ink-2)}
.ui-page-meta{flex-basis:100%;margin:0;font-size:var(--fs-caption);line-height:1.5;color:var(--muted)}
.ui-page-actions{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-2);margin-left:auto}
.ui-page-head--doc{display:block;border-bottom:1.5px solid var(--ink)}
.ui-page-head--doc>h1{font-size:var(--fs-title-doc)}
.ui-page-head--doc>.ui-page-eyebrow{margin-bottom:var(--sp-1)}
.ui-page-head--doc>.ui-page-lede{max-width:720px;margin-top:var(--sp-2);font-size:var(--fs-body);line-height:1.6}
.ui-page-head--doc>.ui-page-meta{margin-top:var(--sp-2)}
.ui-page-head--doc>.ui-page-actions{margin-top:var(--sp-3)}
.ui-page-head--tool{border-bottom:1px solid var(--rule)}
.ui-page-head--tool>h1{min-width:0;font-size:var(--fs-title-tool);overflow-wrap:anywhere;text-wrap:balance}
.ui-page-head--tool>.ui-page-lede{flex:1 1 420px;min-width:0;font-size:var(--fs-meta);line-height:1.5;color:var(--muted)}
/* 조작 화면은 동작 칸을 확인일 줄 오른쪽에 붙여 한 줄을 줄인다(2026-11-09 운영자 「세로 여백이 너무 많다」) */
.ui-page-head--tool>.ui-page-meta{flex:1 1 240px;min-width:0}
.ui-page-head--tool>.ui-page-actions{order:1}
/* 제목을 숨긴 머리(hiddenTitle): 설명이 첫 줄이 된다 */
.ui-page-head--untitled>.ui-page-lede{margin-top:0}
/* 제목이 없으면 머리 아래 선을 긋지 않는다. 바로 아래 탭·하위 메뉴·칩 줄이 구분 역할을 한다(2026-11-09 운영자 「세로 여백이 너무 많다」) */
.ui-page-head.ui-page-head--untitled{margin-bottom:var(--sp-3);padding-bottom:0;border-bottom:0}
/* 설명 접기(pageHead fold, web/js/ss-intro.js): 접으면 설명·확인일 줄을 숨기고 단추만 남는다 */
html[data-ss-intro-folded] .ui-page-head[data-intro-fold]>:is(.ui-page-lede,.ui-page-meta){display:none}
/* 단추가 아래 탭 줄로 간 머리(data-ss-intro="tabs")는 접으면 보일 것이 없으므로 자리도 차지하지 않는다(2026-11-10 운영자) */
html[data-ss-intro-folded] .ui-page-head.ui-page-head--untitled[data-ss-intro="tabs"]{margin:0;padding:0}
@media(max-width:600px){
  .ui-page-head{margin-bottom:var(--sp-3);padding-bottom:var(--sp-2)}
  .ui-page-head--tool>.ui-page-lede{flex-basis:100%}
  .ui-page-head.ui-page-head--untitled{margin-bottom:var(--sp-2)}
  .ui-page-head--tool>.ui-page-meta{flex-basis:0}
  .ui-page-head--tool>.ui-page-actions{align-self:flex-start}
}

/* ---------- 하위 메뉴: subnav() — 메뉴 안의 다른 화면(주소가 바뀜) ----------
   2026-11-11 운영자가 고른 B-4: 묶음 상자 없이 이름 길이대로, 지금 화면만 초록 8px 칸 + 굵은 글씨. */
.ui-subnav{display:flex;gap:2px;width:max-content;max-width:100%;margin:0 0 var(--sp-3);overflow-x:auto;scrollbar-width:none}
.ui-subnav::-webkit-scrollbar{display:none}
.ui-subnav>a,.ui-subnav>button{flex:none;display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:var(--ctl-sm);padding:0 var(--sp-3);border:0;border-radius:var(--r-sm);background:none;font:inherit;font-size:var(--fs-control);font-weight:400;line-height:1.2;color:var(--ink-2);text-decoration:none;white-space:nowrap;cursor:pointer}
.ui-subnav>a:not([aria-current]):hover,.ui-subnav>button:not([aria-current]):hover{color:var(--ink);background:var(--paper-2)}
.ui-subnav>[aria-current="page"]{background:var(--signal);font-weight:700;color:var(--ink)}
/* 화면 맨 위 하위 메뉴(2026-11-10 운영자 「여백 없는게 좋아」): 화면마다 다른 .page-in 위 여백(2~28px)을 무시하고
   머리글 선에서 언제나 8px에 둔다. 하위 메뉴가 첫 줄인지(바로 아래 또는 감싼 상자 하나 안)만 보고 정하므로 화면 CSS에서 따로 맞추지 않는다. */
.app>.page>.page-in:has(>.ui-subnav:first-child,>:first-child>.ui-subnav:first-child){padding-top:var(--sp-2)}
@media(max-width:600px){
  .ui-subnav{gap:0;margin-bottom:var(--sp-2)}
  /* 폰: 칸 사이 간격을 없애고 안쪽 여백만 줄인다(375px 폭에서도 네 칸이 들어간다). 이름 길이대로 왼쪽부터 놓고, 넘치면 줄을 바꾸지 않고 가로로 넘긴다 */
  .ui-subnav>a,.ui-subnav>button{padding:0 6px}
}

/* ---------- 화면 안 탭: tabs() — 같은 화면의 내용 묶음 전환 ---------- */
.ui-tabs{display:flex;gap:var(--sp-5);margin:0 0 var(--sp-3);border-bottom:1px solid var(--rule);overflow-x:auto;scrollbar-width:none}
.ui-tabs::-webkit-scrollbar{display:none}
.ui-tabs>button,.ui-tabs>a{position:relative;flex:none;display:inline-flex;align-items:center;gap:6px;min-height:var(--ctl-lg);padding:0;border:0;background:none;font:inherit;font-size:var(--fs-control);font-weight:400;color:var(--muted);text-decoration:none;white-space:nowrap;cursor:pointer}
.ui-tabs>button:hover,.ui-tabs>a:hover{color:var(--ink)}
.ui-tabs>[aria-selected="true"],.ui-tabs>[aria-current="page"]{font-weight:700;color:var(--ink)}
.ui-tabs>[aria-selected="true"]::after,.ui-tabs>[aria-current="page"]::after{content:"";position:absolute;left:0;right:0;bottom:-1px;height:3px;background:var(--accent)}
.ui-tabs .num{font-family:var(--num);font-weight:700;color:var(--faint)}
.ui-tab-tag{padding:1px 6px;border-radius:var(--r-xs);background:var(--warn-soft);font-size:var(--fs-caption);font-weight:700;color:var(--ink-2)}
@media(max-width:600px){
  .ui-tabs{gap:var(--sp-4);margin-bottom:var(--sp-2)}
  .ui-tabs>button,.ui-tabs>a{min-height:var(--ctl-md)}
}

/* ---------- 보기 전환: seg() — 2~5개 값 중 하나 ---------- */
.ui-seg{display:inline-flex;align-items:center;gap:2px;max-width:100%;padding:3px;border-radius:var(--r-pill);background:var(--paper-2);overflow-x:auto;scrollbar-width:none}
.ui-seg::-webkit-scrollbar{display:none}
.ui-seg-label{flex:none;padding:0 var(--sp-2) 0 var(--sp-3);font-size:var(--fs-caption);font-weight:700;color:var(--muted)}
.ui-seg>button{flex:none;min-height:var(--ctl-sm);padding:0 var(--sp-3);border:0;border-radius:var(--r-pill);background:none;font:inherit;font-size:var(--fs-meta);color:var(--ink-2);white-space:nowrap;cursor:pointer}
.ui-seg>button:hover{color:var(--ink)}
.ui-seg>button[aria-pressed="true"]{background:var(--card);font-weight:700;color:var(--ink);box-shadow:0 0 0 1px var(--rule),0 1px 2px oklch(20% .012 250 / .12)}

/* ---------- 칩: chip() — 고르기(여러 개 가능). 누를 수 없는 것은 칩이 아니라 배지 ---------- */
.ui-chips{display:flex;flex-wrap:wrap;gap:6px}
.ui-chips--scroll{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none}
.ui-chips--scroll::-webkit-scrollbar{display:none}
.ui-chip{flex:none;display:inline-flex;align-items:center;gap:6px;min-height:var(--ctl-sm);padding:0 var(--sp-3);border:1px solid var(--rule);border-radius:var(--r-pill);background:var(--card);font:inherit;font-size:var(--fs-meta);color:var(--ink);white-space:nowrap;cursor:pointer}
.ui-chip:hover,.ui-chip:focus-visible{border-color:var(--ink-2)}
/* 고른 칩은 먹색 칸(2026-11-09 운영자 「검은 칸이 더 잘 보인다」). 어두운 화면에서는 --ink·--paper가 뒤바뀌어 밝은 칸 + 어두운 글자가 된다 */
.ui-chip[aria-pressed="true"]{border-color:var(--ink);background:var(--ink);font-weight:700;color:var(--paper)}
.ui-chip[aria-pressed="true"]:hover,.ui-chip[aria-pressed="true"]:focus-visible{border-color:var(--ink)}
.ui-chip[disabled]{opacity:.4;cursor:default}
.ui-chip .num{font-family:var(--num);font-weight:700;color:var(--muted)}
.ui-chip[aria-pressed="true"] .num{color:var(--paper);opacity:.75}
.ui-chip--logo{min-height:var(--ctl-md);padding:0 var(--sp-3) 0 6px}
/* 로고는 언제나 흰 판(--icon-bg) 위에 둔다: 먹색 칸·어두운 화면에서도 체인 색이 그대로 보인다 */
.ui-chip--logo .bi,.ui-chip--logo>img{width:24px;height:24px;object-fit:contain}
.ui-chip--logo>img{border-radius:50%;background:var(--icon-bg)}

/* ---------- 배지: badge() — 상태·분류 표시(누르지 않는다) ---------- */
.ui-badge{display:inline-flex;align-items:center;gap:4px;padding:1px 6px;border-radius:var(--r-xs);background:var(--paper-2);font-size:var(--fs-caption);font-weight:700;line-height:1.5;color:var(--ink-2);white-space:nowrap;vertical-align:1px}
.ui-badge--ok{background:var(--ok-soft);color:var(--ok-ink)}
.ui-badge--warn{background:var(--warn-soft);color:var(--warn-ink)}
.ui-badge--bad{background:var(--bad-soft);color:var(--bad)}
.ui-badge--quiet{padding:0;background:none;font-weight:400;color:var(--muted)}

/* ---------- 버튼: button() ---------- */
.ui-btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:var(--ctl-md);padding:0 var(--sp-4);border:1px solid var(--rule);border-radius:var(--r-sm);background:var(--card);font:inherit;font-size:var(--fs-control);font-weight:700;color:var(--ink);text-decoration:none;white-space:nowrap;cursor:pointer}
.ui-btn:hover{border-color:var(--ink-2)}
.ui-btn--primary{border-color:var(--accent);background:var(--accent);color:var(--card)}
.ui-btn--primary:hover{border-color:var(--accent-hover);background:var(--accent-hover)}
.ui-btn--text{min-height:auto;padding:0;border:0;background:none;color:var(--accent);text-decoration:underline;text-underline-offset:3px}
.ui-btn--quiet{min-height:var(--ctl-sm);padding:0;border:0;background:none;font-size:var(--fs-caption);font-weight:400;color:var(--muted);text-decoration:underline;text-underline-offset:3px}
.ui-btn--quiet:hover{color:var(--ink)}
.ui-btn--lg{min-height:var(--ctl-lg)}

/* ---------- 안내·빈 상태: notice() · empty() ---------- */
.ui-notice{margin:var(--sp-3) 0;font-size:var(--fs-meta);line-height:1.6;color:var(--ink-2)}
.ui-notice>b{color:var(--ink)}
.ui-notice--warn{color:var(--warn-ink)}
.ui-empty{display:grid;justify-items:start;gap:var(--sp-2);padding:var(--sp-6) 0;font-size:var(--fs-body);color:var(--muted)}
.ui-empty>b{font-size:var(--fs-item);color:var(--ink)}
@media(prefers-reduced-motion:reduce){.ui-subnav,.ui-tabs,.ui-seg,.ui-chips--scroll{scroll-behavior:auto}}
