/* 구현에만 있는 것 — 목업에 짝이 없는 몇 가지.
 *
 * 옷은 theme.css 하나가 입힌다(목업과 같은 파일). 여기에는 **목업에 없는 것**만
 * 둔다. 지금은 둘뿐이다 —
 *   · 목업 바로가기 띠 (목업 자신에게는 필요 없다)
 *   · 로그인 팝업의 여닫기 (목업은 login.js 가 껍데기째 만들어 붙인다)
 *
 * 여기가 자꾸 길어지면 신호다 — 목업에 없는 화면을 그리고 있다는 뜻이다.
 */

/* ── 로그인 팝업 ──────────────────────────────────────
 * 목업은 login.js 가 .back.lgscrim 을 만들어 붙였다 뗀다. 구현은 마크업을
 * 미리 두고 여닫으므로 숨기는 규칙이 필요하다. 안 두었더니 껍데기가 모든
 * 화면에 펼쳐져 아이콘이 화면만 하게 나왔다.
 * 속옷(.lgnote · .lglab · .lgpw …)은 theme.css 가 이미 갖고 있다. */
.mo{position:fixed;inset:0;z-index:70;display:none;place-items:center;padding:20px;
  background:var(--scrim,rgba(20,22,26,.42))}
body.login .mo{display:grid}

/* ── 목업 바로가기 ────────────────────────────────────
 * 우측 하단에 떠 있다. 첫 화면이 구현으로 옮겨 온 뒤로는 목업으로 가는 유일한 길이다. */
.mockgo{position:fixed;bottom:16px;right:16px;z-index:60;
  display:inline-flex;align-items:center;gap:10px;padding:9px 13px 9px 11px;
  border-radius:999px;border:1px solid rgba(255,255,255,.16);
  background:rgba(26,26,26,.92);color:#fff;text-decoration:none;
  box-shadow:0 4px 10px rgba(0,0,0,.16),0 14px 34px rgba(0,0,0,.22);
  transition:transform .2s,box-shadow .2s,background .2s}
.mockgo:hover{transform:translateY(-2px);background:#1A1A1A;text-decoration:none}
.mockgo:focus-visible{outline:2px solid #fff;outline-offset:2px}
.mockgo-i{flex:none;width:26px;height:26px;border-radius:8px;display:grid;
  place-items:center;background:rgba(255,255,255,.14)}
.mockgo-i svg{width:15px;height:15px}
.mockgo-t{display:flex;flex-direction:column;line-height:1.25}
.mockgo-t b{font-size:13px;font-weight:700;letter-spacing:-.01em}
.mockgo-t span{font-size:11px;color:rgba(255,255,255,.62)}
.mockgo-o{flex:none;opacity:.55}
.mockgo-o svg{width:13px;height:13px}
/* 좁은 화면에서는 글자를 접고 아이콘만 남긴다 */
@media (max-width:560px){
  .mockgo{padding:9px;gap:0}
  .mockgo-t,.mockgo-o{display:none}
}

/* ── 팝업을 여는 자리 ─────────────────────────────────
 * 목업은 `<a href="#">` 으로 열지만, 구현에서는 단추로 둔다 — 팝업을 여는 것은
 * 옮겨 가는 것이 아니고, href="#" 는 아무 데도 안 가는 죽은 링크처럼 읽힌다.
 * 옆의 링크들과 같은 모양이어야 하므로 단추 옷을 벗긴다. */
.zfoot button.zgo{border:0;background:none;padding:0;cursor:pointer;
  font:600 var(--t-small)/1.4 inherit;color:var(--accent);white-space:nowrap}
.zfoot button.zgo:hover{text-decoration:underline}

/* ── 로그인 팝업 ──────────────────────────────────────
 * 속옷(.lgnote · .lglab · .lgpw · .lgrule · .lgways)은 theme.css 가 갖는다.
 * 여기에는 **구현에만 있는 것**만 둔다 — 목업은 팝업을 JS 가 만들어 붙였다 뗐지만
 * 구현은 마크업을 미리 두고 여닫으므로 그 규칙이 필요하다. */
.lghead{display:flex;align-items:center;gap:10px;margin:0 0 6px}
.lghead h2{flex:1;min-width:0;margin:0}
.lgx{border:0;background:none;padding:4px;cursor:pointer;color:var(--dim);
  font-size:16px;line-height:1}
.lgx:hover{color:var(--ink)}
/* 비밀번호 규칙 — 지킨 것에 표시가 붙는다. login.js 가 .ok 를 켠다 */
.lgpol{list-style:none;margin:-8px 0 14px;padding:0;display:grid;gap:4px}
.lgpol li{font-size:12px;color:var(--dim);padding-left:16px;position:relative}
.lgpol li::before{content:"○";position:absolute;left:0}
.lgpol li.ok{color:var(--ok)}
.lgpol li.ok::before{content:"●"}
/* 걸음 표시 — 로그인 한 걸음일 때는 감춘다 */
.lgmodal .steps3{margin:0 0 16px}

/* ── 업무 기반 추천 팝업 ──────────────────────────────
 * 목업은 ob.js 가 판을 만들어 붙였다 뗐다. 구현은 폼으로 두고 여닫으므로
 * 그만큼의 규칙이 필요하다. 속옷(.obq · .obc · .obw …)은 theme.css 가 갖는다. */
#ob{display:none}
#ob:not([hidden]){display:grid;place-items:center}

/* ── 라디오·체크박스를 칩으로 ─────────────────────────
 * 목업은 이 자리에 button 을 세우고 JS 가 상태를 쥔다. 구현은 폼으로 보내야 하므로
 * 진짜 input 을 쓰고 옷만 칩으로 입힌다 — JS 가 없어도 고르고 보낼 수 있다.
 * 켜진 것은 CSS 가 판단한다(:has). 서버가 on 을 같이 적으면 눌러 옮긴 뒤
 * 두 칸이 골라진 것처럼 보인다. */
.chips.pick .chip{position:relative;cursor:pointer}
.chips.pick .chip input{position:absolute;opacity:0;width:0;height:0}
.chips.pick .chip:has(input:checked){
  background:var(--accent);border-color:var(--accent);color:#fff;font-weight:700}
.chips.pick .chip:has(input:focus-visible){outline:2px solid var(--accent);outline-offset:2px}

/* ── 처리함 · 등록 검수 ───────────────────────────────
 * 목업은 줄을 눌러 그 자리에서 펼치고 JS 가 몸통을 그린다. 구현은 검수 상세로
 * 보내므로 .ibhead 를 button 이 아니라 a 로 세운다 — 링크 밑줄과 색을 지운다.
 * 모양은 theme.css 의 .ibhead 가 그대로 갖는다. */
a.ibhead{text-decoration:none;color:inherit}
a.ibhead .nm{text-decoration:none}
a.ibhead:hover .nm{text-decoration:underline}

/* 등록 검수는 결정 줄이 폼이다 — 목업은 눌러 고른 뒤 한 번 더 보내지만
 * 구현은 단추 셋이 곧 결정이라 판 이름을 label 로 쓴다 */
.rvact label.note{margin:0;font-weight:700;color:var(--n-900)}
.rvact label.note b{font-weight:700;color:var(--dim)}

/* ── 한 일을 알리는 띠 ─────────────────────────────────
 * 되돌려 놓고 아무 말도 하지 않으면 눌린 것이 먹었는지 알 수 없다.
 * 목업은 이 자리를 JS 로 띄웠다 붙였다 해서 이름이 없다 — 여기서 하나 세운다.
 * 한 이름으로 둘을 가른다(CM-13): 된 것은 .flash, 안 된 것은 .flash.miss.
 * .warnbox 를 쓰면 잘 된 일에 경고 색이 붙는다. */
.flash{
  margin:0 0 16px; padding:13px 18px; border-radius:var(--r-s);
  background:var(--ok-bg); color:var(--ok);
  font-size:var(--t-small); font-weight:700;
}
.flash.miss{background:var(--warn-bg); color:var(--warn-ink)}

/* ── 올리기 (SC-26) ───────────────────────────────────
 * 목업은 유형 카드와 공개범위를 button 으로 세우고 JS 가 고른 것을 쥔다.
 * 구현은 폼으로 보내야 하므로 진짜 라디오를 쓰고 옷만 그 모양으로 입힌다 —
 * JS 가 없어도 고르고 보낼 수 있다. 모양은 theme.css 의 .pcard · .wayopt 가
 * 그대로 갖고, 여기서는 라디오를 감추고 켜진 것을 CSS 로 판단한다. */
.pcard input, .wayopt input{position:absolute;opacity:0;width:0;height:0}
.pcard:has(input:checked){border-color:var(--accent);box-shadow:0 0 0 1px var(--accent)}
.wayopt:has(input:checked){border-color:var(--accent);background:var(--accent-bg)}
.wayopt:has(input:checked) .chk{border-color:var(--accent);background:var(--accent)}
.wayopt:has(input:checked) .chk::before{content:"✓"}
/* theme.css 가 .chk 를 두 가지로 쓴다 — 검증 결과 줄(padding:18px 20px)과
 * 고르개의 네모 표시(18×18). 한 이름이 두 가지라 앞의 안쪽 여백이 뒤에 얹혀
 * 표시가 두 배로 부푼다. 목업도 같이 겪는 것이라 theme.css 를 건드리지 않고
 * 여기서 이 자리만 못 박는다. */
.wayopt .chk{padding:0}
.pcard:has(input:focus-visible),.wayopt:has(input:focus-visible){
  outline:2px solid var(--focus-ring);outline-offset:2px}

/* 스킬 만드는 절차 — 목업 register 에는 이 안내가 없다(목업은 스킬이 이미
 * 있다고 본다). 실제로는 여기서 처음 만드는 사람이 많아 자리를 둔다. */
.howto{margin:14px 0 0;padding:0;list-style:none;counter-reset:h}
.howto > li{
  position:relative;padding:0 0 0 34px;margin-top:18px;counter-increment:h}
.howto > li:first-child{margin-top:0}
.howto > li::before{
  content:counter(h);position:absolute;left:0;top:0;
  display:flex;align-items:center;justify-content:center;
  width:24px;height:24px;border-radius:50%;
  background:var(--sunken);color:var(--dim);font-size:12px;font-weight:800}
.howto > li > b{display:block;font-size:var(--t-small);font-weight:700;color:var(--n-900)}
.howto > li > p{margin-top:6px;font-size:var(--t-small);color:var(--ink);line-height:1.7}
/* 안내 안의 코드 조각은 옮겨 적을 것이라 줄을 접지 않는다 */
.howto .copybox pre{white-space:pre}

/* 주소 칸은 겉 테두리가 감싼다 — 안쪽 input 이 제 테두리를 갖지 않는다.
 * type 을 안 적어 .frow2 input[type=text] 가 걸리지 않게 했지만,
 * 뒤에 누가 type 을 적어도 깨지지 않도록 여기서 못 박는다. */
.frow2 .slug input{border:0;padding:0 10px;background:none;border-radius:0}

/* ── 아직 안 만든 자리 ────────────────────────────────
 * 목업은 모든 화면이 있어서 이런 표시가 필요 없다. 구현은 아직 없는 것이
 * 있고, 살아 있는 링크와 똑같이 보이면 눌러 보고서야 안다(CM-15).
 * 흐리게 두고 손 모양을 막는다 — 링크가 아니라는 것이 눌러 보기 전에 보여야
 * 한다. 화면이 서면 이 칸은 저절로 링크가 된다(base.html 이 href 로 가른다). */
.gnav a.soon, .subtab.soon{color:var(--faint);cursor:not-allowed}
.gnav a.soon:hover, .subtab.soon:hover{color:var(--faint)}

/* 업무 추천 판의 '다시 고르기' — 판 안의 작은 글자 단추다. 단추 기본 옷을
 * 입으면 회색 네모가 되어 카드 가운데 튄다. */
.obh{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
.obedit{
  margin-left:auto;border:0;background:none;padding:0;cursor:pointer;
  font:inherit;font-size:12px;font-weight:700;color:var(--accent-ink);
  text-decoration:underline;text-underline-offset:2px}
.obedit:hover{color:var(--accent)}

/* 기간 두 칸 — 물결표를 사이에 두고 한 줄로 */
.per{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.per input{flex:1;min-width:150px}
.per .tilde{flex:none;color:var(--dim)}

/* ── 조직도에서 사람 고르기 ───────────────────────────
 * 목업은 오른쪽에서 밀려 나오는 판(.rnb)을 스크립트가 세운다. 구현은 폼으로
 * 보내야 해서 칸 안에서 접었다 편다 — <details> 하나면 스크립트 없이도
 * 펼치고 고를 수 있다. 고른 결과(사번)는 어느 쪽으로 골라도 같다. */
.orgpick{
  margin-top:10px;padding:12px 14px;max-height:420px;overflow-y:auto;
  border:1px solid var(--line);border-radius:var(--r-s);background:var(--n-50)}
.orgpick > .note{margin:0 0 10px}
.orgnode{margin-left:0}
.orgnode .orgnode{margin-left:14px;padding-left:10px;border-left:1px solid var(--line)}
.orgnode > summary{
  padding:6px 2px;cursor:pointer;list-style:none;
  font-size:var(--t-small);font-weight:700;color:var(--n-900)}
.orgnode > summary::-webkit-details-marker{display:none}
/* 펼침 표시는 글자로 둔다 — 아이콘을 넣으면 크기를 줄 자리가 또 필요하다 */
.orgnode > summary::before{content:"▸ ";color:var(--faint);font-weight:400}
.orgnode[open] > summary::before{content:"▾ "}
.orgnode > summary:hover{color:var(--accent-ink)}
.orgnode > summary .cnt{
  margin-left:6px;padding:1px 6px;border-radius:999px;
  background:var(--sunken);color:var(--dim);font-size:11px;font-weight:700}
/* 사람 한 줄. 단추와 이미 넣은 줄이 같은 자리에 서야 목록이 안 흔들린다 */
.orgman{
  display:block;text-align:left;margin:1px 0 1px 16px;padding:5px 9px;
  border:0;border-radius:var(--r-s);background:none;cursor:pointer;
  font:inherit;font-size:var(--t-small);color:var(--ink)}
button.orgman:hover{background:var(--accent-bg);color:var(--accent-ink)}
.orgman .d{margin-left:6px;color:var(--dim);font-size:12px}
.orgman.took{cursor:default;color:var(--dim)}
.orgman .already{margin-left:8px;font-size:11px;font-weight:700;color:var(--ok)}
/* DID 에 메일이 없어 아직 들어오지 못하는 사람. **고르는 것을 막지는
   않는다** — 조직도에서 사람을 지우는 것이 더 나쁘고, 메일은 곧 채워질
   수 있다. 다만 담당자로 앉히면 알림을 열어 볼 수 없으니 적어 둔다 */
.orgman .nomail{margin-left:8px;font-size:11px;font-weight:700;color:var(--warn-ink)}

/* ── 글자수 세기 ──────────────────────────────────────
 * 길이를 막아 두기만 하면 왜 더 안 써지는지 모른다 — 남은 자리를 늘 보여 둔다.
 * 칸 바로 뒤 오른쪽에 붙는다. 자리를 차지해 칸을 밀지 않게 블록으로 두고
 * 오른쪽 끝에 세운다. */
.cin{
  display:block;margin-top:4px;text-align:right;
  font-size:11px;color:var(--faint);font-variant-numeric:tabular-nums}
/* 거의 다 찼을 때 미리 알린다 — 다 차고 나서 알리면 이미 늦다 */
.cin.near{color:var(--warn-ink);font-weight:700}
.cin.full{color:var(--danger);font-weight:700}

/* ── 적은 대로 보여 준다 ──────────────────────────────
 * HTML 은 줄바꿈을 공백으로 접는다. 여러 줄 칸(하는 일 · 다루는 데이터 ·
 * 목적 · 남긴 말)에 번호를 매겨 줄줄이 적어도 상세에서는 한 덩어리로 붙는다.
 * 사장님이 1·2·3·4 로 나눠 적은 것이 한 문단으로 나와 지적받았다(2026-09-14).
 *
 * `pre-line` 은 **줄바꿈만** 살리고 이어지는 공백과 줄맞춤은 접는다 —
 * `pre` 로 두면 길어질 때 가로로 삐져나가고, 붙여넣은 들여쓰기까지 그대로 선다.
 *
 * 목록 카드(.acard .ad)에는 쓰지 않는다. 거기는 두 줄로 잘라 보여 주는
 * 자리라 줄바꿈을 살리면 첫 줄만 보이고 만다. */
.keeplines{white-space:pre-line}

/* ── 알림 줄 ──────────────────────────────────────────
 * 목업은 줄 전체가 링크(`<a>`)다. 구현은 **누르면 읽음까지 남겨야** 해서
 * 폼으로 보낸다 — 링크로는 서버에 아무것도 못 남긴다. 모양은 목업의
 * `.nfrow a` 가 가진 것을 그대로 쓰고, 단추 기본 옷만 벗긴다. */
.nfrow > form{display:contents}
.nfgo{
  display:flex;align-items:center;gap:10px;width:100%;
  padding:13px 16px;border:0;background:none;cursor:pointer;
  font:inherit;font-size:var(--t-small);text-align:left;color:inherit}
.nfgo:hover{background:var(--sunken)}
/* 안 읽은 줄은 바탕으로 가른다 — 점 하나만으로는 목록에서 눈에 띄지 않는다 */
.nfrow.new .nfgo,
.nfrow.new .nfgo:hover{background:var(--accent-bg)}
.nfrow.new .nfgo .nft{font-weight:700}
.nfgo:hover .nft{text-decoration:underline}
.nfgo:focus-visible{outline:2px solid var(--focus-ring);outline-offset:-2px}
/* 딸린 말은 제목 **뒤에 잇는다.** 아래로 내리면 그 줄만 키가 커져
 * 목록이 들쭉날쭉해진다 — 목업 줄은 모두 한 줄 높이다. */
.nft > em{
  margin-left:8px;font-style:normal;color:var(--dim);font-size:12px;font-weight:400}


/* 상세 한 줄 지표 — 세운 칸 수만큼만 나눈다 (SC-04).
   theme.css 는 늘 여섯으로 나눈다. 목업은 여섯을 다 채우지만 실물은
   모르는 것을 안 세우므로 넷이면 왼쪽으로 몰려 붙었다.
   좁은 화면 규칙은 theme.css 가 !important 로 덮어 그대로 둔다. */
.sum{grid-template-columns:repeat(var(--n,6),1fr)}

/* 탭을 링크로 쓴다 — 주소에 탭이 담겨야 새로고침과 뒤로가기가 산다.
   theme.css 의 `.tab` 은 button 을 보고 만든 것이라 a 에 필요한 것만 더한다. */
a.tab{text-decoration:none; display:inline-block}
a.tab:hover{text-decoration:none}


/* 걸음 표시가 두 줄로 갈라지던 것 — "본인 확 / 인" (SC-34).
   판은 400px 인데 걸음 셋을 늘어놓으면 400px 을 넘는다. 넘친 만큼
   글자가 접혀 걸음 이름이 두 줄이 됐다.

   **글자를 접지 않고, 남는 자리는 잇는 줄이 먹는다.** 판을 넓히는 것만으로는
   폰 너비에서 또 접힌다 — 줄어들 수 있는 것이 하나는 있어야 한다.
   그 자리는 잇는 줄(`.bar`)이다. 걸음 이름은 줄어들 수 없는 것이고,
   접히면 무슨 걸음인지 읽기 어려워진다. */
.lgmodal{width:min(440px, calc(100vw - 32px))}
.lgmodal .s3{padding-right:0; min-width:0}
.lgmodal .s3 b{white-space:nowrap}
.lgmodal .s3 .bar{flex:1 1 auto; width:auto; min-width:10px; margin:0 9px}


/* 첨부 이미지 — 목업은 자리만 그려 둔 판(`.ph`)이라 실물 그림 규칙이 없다.
   판 너비를 넘지 않게 하고 비율은 그대로 둔다. */
.shots img{display:block; width:100%; height:150px; object-fit:cover;
           border:1px solid var(--line); border-radius:var(--r-s); background:var(--n-50)}


/* 자산 관리에서 그림을 빼는 단추 — 설명 줄 오른쪽 끝에 붙는다 */
.shots figcaption form{float:right; margin-left:8px}
.shots figcaption{min-height:22px}


/* 그림 넣기 — 끌어다 놓는 판과 미리보기 (SC-04 개요).
   `.drop` 은 목업 register.html 이 쓰던 판이다. 여기서는 `label` 이라
   눌러도 골라지므로 손 모양을 준다. */
label.drop{display:block; cursor:pointer}
label.drop:hover{border-color:var(--accent); background:var(--accent-bg)}
/* 끌어 온 것이 판 위에 있을 때 — 여기 놓으면 된다는 것을 보여 준다 */
.drop.on{border-color:var(--accent); background:var(--accent-bg)}
.shotprev{margin:12px 0 0; display:flex; align-items:center; gap:12px}
.shotprev img{
  width:120px; height:80px; object-fit:cover; flex:none;
  border:1px solid var(--line); border-radius:var(--r-s); background:var(--n-50);
}
.shotprev figcaption{font-size:12px; color:var(--dim); line-height:1.6; word-break:break-all}


/* 빈 화면의 글 속 굵은 글씨가 줄을 끊던 것.
   `.empty b` 는 **제목**을 한 줄로 세우려고 `display:block` 인데, 글(`p`)
   안의 `<b>` 까지 걸려 한 낱말마다 줄이 바뀌었다 — 가운데 맞춤이라 더
   읽기 어려웠다. 제목은 `.empty > b` 가 그대로 맡고, 글 속은 되돌린다. */
.empty p b{display:inline}


/* 글자수 세기가 줄을 밀던 것.
   `.gdrow` 는 `76px 1fr` 두 칸짜리 격자다. 세는 표시(`.cin`)는 칸 바로
   뒤에 끼워지므로 **세 번째 칸**이 되어 다음 줄 왼쪽(이름 자리)으로
   떨어졌다. 칸 밑에 붙도록 둘째 열에 자리를 잡아 준다. */
.gdrow .cin{grid-column:2; margin-top:-5px}

/* 이름 · 칸 · 단추를 한 줄에. 따로 세우면 칸 하나 넣는 자리가 네 줄을
   잡아먹는다(설명 · 세는 표시 · 안내 · 단추). */
.gdrow.gdsend{grid-template-columns:76px 1fr auto; align-items:center}

/* 끌어다 놓는 판이 너무 두껍다 — 글 두 줄에 26px 씩이면 판이 화면을
   반쯤 차지한다. 안내는 아래 글에도 있으니 여기서는 얇게. */
.gdbox .drop{padding:16px 20px}


/* 푸시에서 바뀐 파일 (기획서 §7.0).
   목업 `files` 를 그대로 그린다 — 더함 · 고침 · 지움을 색으로 가른다. */
.pushcard + .pushcard{margin-top:16px}

/* 커밋 상세 — `js_commit.js` 가 오른쪽 판으로 옮긴다. 스크립트가 막힌
   자리에서는 이 자리에 그대로 펼쳐진 채 읽힌다. */
.cmtsrc{margin:16px 0 0; padding-top:16px; border-top:1px solid var(--line)}
.cmtsrc .cmt-h:first-child{margin-top:0}
.rnb .cmtsrc{margin:0; padding-top:0; border-top:0}
.flist{list-style:none; margin:12px 0 0; padding:0; display:grid; gap:4px}
.flist li{display:flex; align-items:center; gap:9px; font-size:12px}
.flist .fk{
  flex:none; min-width:34px; padding:1px 7px; border-radius:var(--r-s);
  text-align:center; font-weight:700; font-size:11px;
}
.flist .fk.add{background:var(--ok-bg); color:var(--ok)}
.flist .fk.mod{background:var(--warn-bg); color:var(--warn-ink)}
.flist .fk.del{background:var(--danger-bg); color:var(--danger)}
.flist .fp{font-family:var(--mono); color:var(--ink); word-break:break-all}


/* 커밋 판의 바뀐 파일 묶음 머리 — 더함 · 고침 · 지움.
   한 줄씩 색으로만 갈라 놓았더니 파일이 스무 개만 돼도 무엇이 새로
   생겼는지 훑어서는 못 찾았다. 묶음마다 이름과 개수를 얹는다. */
.cmt-g{
  display:flex; align-items:center; gap:8px;
  margin:14px 0 6px; padding-bottom:6px; border-bottom:1px solid var(--line);
}
.cmt-g:first-of-type{margin-top:4px}
.cmt-g .m{
  flex:none; padding:2px 9px; border-radius:var(--r-s);
  font-size:11px; font-weight:700;
}
.cmt-g .m.a{background:var(--ok-bg); color:var(--ok)}
.cmt-g .m.m{background:var(--warn-bg); color:var(--warn-ink)}
.cmt-g .m.d{background:var(--danger-bg); color:var(--danger)}
.cmt-g .m.x{background:var(--n-100); color:var(--dim)}

/* 묶음 안의 파일 줄.
   경로를 한 줄로 이어 붙여 놓았더니 목록이 아니라 글 덩어리로 읽혔다.
   줄마다 파일 그림을 두고, 판을 깔아 낱낱으로 보이게 하고, 폴더는 흐리게
   파일 이름은 굵게 세운다 — 찾는 것은 이름이다. */
.cmt-g + .cmt-f{margin:0 0 4px; display:grid; gap:4px}
.cmt-g + .cmt-f li{
  display:flex; align-items:center; gap:9px;
  padding:7px 11px; border-top:0; border-radius:var(--r-s);
  background:var(--n-50);
}
.cmt-f .fic{flex:none; display:flex; width:15px; height:15px; color:var(--dim)}
.cmt-f .fic svg{width:15px; height:15px}
/* 그림 색이 묶음을 따라간다 — 머리글을 지나쳐 내려온 뒤에도 갈린다 */
.cmt-f.k-a .fic{color:var(--ok)}
.cmt-f.k-m .fic{color:var(--warn-ink)}
.cmt-f.k-d .fic{color:var(--danger)}
.cmt-g + .cmt-f .pth{
  min-width:0; font-family:var(--mono); font-size:12px;
  color:var(--dim); word-break:break-all;
}
.cmt-f .pth .dir{color:var(--faint)}
.cmt-f .pth b{font-weight:700; color:var(--n-900)}
/* 지운 파일은 이제 없는 파일이다 — 이름에 줄을 긋는다 */
.cmt-f.k-d .pth b{text-decoration:line-through; text-decoration-thickness:1px}

/* ── 커밋 판의 라벨과 머리글 ──────────────────────────────────
   커밋 번호와 가지 이름은 라벨이다. 글줄에 섞어 두면 어디까지가 번호인지
   눈으로 끊어야 한다.

   모양은 목업 `.pushed .br` · `.pushed .sha` 와 **같아야 한다** — 같은 것을
   두 자리에서 쓰니 다르게 보이면 다른 것으로 읽힌다. 그 규칙이 `.pushed`
   안에만 걸려 있어 판에서 다시 적는다(theme.css:1836 과 함께 고칠 것). */
.rnb-h .sha,
.cmt-sub .br{
  display:inline-block; padding:2px 8px; border-radius:var(--r-s);
  background:var(--n-50); border:1px solid var(--line);
  font-family:var(--mono); font-size:12px; font-weight:400; color:var(--ink);
  vertical-align:middle;
}
.rnb-h h2{display:flex; align-items:center; gap:8px}
.cmt-sub{display:flex; align-items:center; flex-wrap:wrap; gap:6px}

/* 닫기 글자가 글꼴을 타 작게 나왔다 — 판 두 곳(사람 고르기 · 커밋)이 함께 쓴다 */
.rnb-h .x{font-size:17px; line-height:1}

/* 바뀐 파일 머리글과 저장소로 가는 단추는 한 줄이다.
   단추를 목록 아래에 글로 눕혀 두었더니 마지막 파일 이름에 붙어 파일인지
   링크인지 갈리지 않았다. */
.cmt-fh{
  display:flex; align-items:center; gap:12px;
  margin:22px 0 2px; padding-bottom:8px; border-bottom:1px solid var(--line);
}
.cmt-fh .cmt-h{flex:1; min-width:0; margin:0; border-bottom:0; padding-bottom:0}
.cmt-fh .btn{flex:none}
.cmt-fh + .cmt-g:first-of-type{margin-top:10px}

/* 첨부 이미지를 그 자리에서 크게 보는 판 (`js_lightbox.js`).
   새 창을 띄우지 않는다 — 그림 한 장 보려고 허브를 떠나면 보던 자리로
   돌아오려고 뒤로가기를 눌러야 한다. */
.shots a.shotbig{display:block; cursor:zoom-in}
.lbx{padding:24px}
.lbxin{
  position:relative; margin:0; max-width:min(1100px, 92vw); max-height:96vh;
  display:flex; flex-direction:column; gap:10px;
}
.lbxin img{
  max-width:100%; max-height:90vh; object-fit:contain;
  border-radius:var(--r-s); background:var(--surface);
  box-shadow:0 16px 40px rgba(16,24,32,.32);
}
.lbxin figcaption{color:#fff; font-size:var(--t-small); text-align:center}
.lbxx{
  position:absolute; top:-14px; right:-14px; width:32px; height:32px;
  border:0; border-radius:99px; background:var(--surface); color:var(--ink);
  font-size:15px; line-height:1; cursor:pointer;
  box-shadow:0 4px 12px rgba(16,24,32,.28);
}
.lbxx:hover{background:var(--n-100)}
@media(max-width:860px){ .lbxx{top:-12px; right:-6px} }

/* 검증 결과도 커밋과 같은 판에서 본다 — 판을 둘 만들면 열고 닫는 규칙이
   갈라진다(`js_commit.js`). 스크립트가 막히면 이 자리에 그대로 펼쳐진다. */
.scansrc{margin:16px 0 0; padding-top:16px; border-top:1px solid var(--line)}
.rnb .scansrc{margin:0; padding-top:0; border-top:0}

/* ── 배포 파이프라인 (기획서 §7.3) ───────────────────────────
   단계 이름 옆에 판 여는 단추를 둔다. 설명 글 끝에 매달아 두었더니
   글을 다 읽어야 단추가 보였다 — 무엇을 볼 수 있는지는 그 칸을 보는
   순간 알아야 한다. */
.pstep .ptop{display:flex; align-items:center; gap:8px; flex-wrap:wrap}
.pstep .ptop .n{margin-bottom:0}
.pstep .ptop b{flex:1 1 auto; min-width:0}
.pstep .ptop .btn{flex:none}
.pstep .at{display:block; margin-top:7px}

/* 지금 무엇을 하고 있나 — 내려받고 풀고 검사하는 데 몇십 초가 걸린다.
   `검사 중` 한 마디만 보이면 멈춘 것인지 도는 것인지 구별되지 않는다. */
.doing{
  /* 단계 칸과 붙어 있어 어디까지가 칸이고 어디부터 진행인지 안 갈렸다 */
  margin:18px 18px; padding:14px 16px; border-radius:var(--r-s);
  background:var(--n-50); border:1px solid var(--line);
}
.doing > b{display:block; font-size:12px; font-weight:700; color:var(--n-900)}
.doing ol{list-style:none; margin:10px 0 0; padding:0; display:grid; gap:6px}
.doing li{display:flex; align-items:center; gap:9px; font-size:var(--t-small)}
.doing .mk{
  flex:none; display:flex; align-items:center; justify-content:center;
  width:18px; height:18px; border-radius:50%;
  background:var(--n-100); color:var(--dim); font-size:11px;
}
.doing li.done{color:var(--dim)}
.doing li.done .mk{background:var(--ok-bg); color:var(--ok)}
.doing li.now{color:var(--n-900); font-weight:700}
.doing li.now .mk{background:var(--accent); color:#fff}
.doing li.wait{color:var(--faint)}
.doing .note{margin:10px 0 0}

/* 안내문과 단추가 든 판. **글자를 배경에 바로 두지 않는다** —
   판 밖에 떠 있으면 어디까지가 한 덩어리인지 갈리지 않는다.

   **글은 왼쪽에 쌓고 단추는 오른쪽에 둔다.** `.ibact` 는 한 줄짜리
   가로 배치라, 까닭이 여러 줄로 길어지자 제목만 왼쪽에 덩그러니 남고
   그 옆이 통째로 비었다 — 둘이 한 덩어리로 안 읽혔다. */
.card.ibact{
  margin-top:16px; padding:16px 18px;
  display:grid; grid-template-columns:1fr auto; gap:12px 18px;
  align-items:start;
}
.card.ibact > .note{grid-column:1; margin:0}
.card.ibact > .ibquote{grid-column:1; margin:0}
.card.ibact > .spacer{display:none}
.card.ibact > .btn,
.card.ibact > form{grid-column:2; grid-row:1; justify-self:end}
/* **단추가 둘 이상이면 묶어서 넘긴다.** 폼을 나란히 두면 둘 다 같은
   칸(2열 1행)으로 가서 **겹쳐 찍힌다** — 뒤에 온 것이 앞의 것을 덮어
   `아직 안 보입니다` 가 `받았습니다` 밑에 깔렸다(2026-09-17, 이용 자산의
   공유 요청). 칸에 들어가는 것은 이 묶음 하나이고, 그 안에서 옆으로 선다 */
.card.ibact > .acts{
  grid-column:2; grid-row:1; justify-self:end;
  display:flex; align-items:center; gap:8px; flex-wrap:wrap;
}
@media(max-width:720px){
  .card.ibact{grid-template-columns:1fr}
  .card.ibact > .btn,
  .card.ibact > .acts,
  .card.ibact > form{grid-column:1; grid-row:auto; justify-self:start}
}
.note-card{margin-top:12px; padding:14px 18px}

/* 검사 항목 — **막는 것과 적어 두는 것**을 갈라 보인다.
   같게 보이면 담당자가 견본 자료 하나에 배포가 막힌 줄 알고 멈춘다. */
.chkit li.warn .st{background:var(--warn-bg); color:var(--warn-ink)}

/* 파이프라인 격자는 **칸 수를 따라간다.**
   목업이 넷이라 `repeat(4,1fr)` 로 박혀 있었는데, 스테이징을 빼 셋이 되자
   오른쪽 한 칸이 빈 채로 남았다. 칸 수는 `queries.PIPE_NAMES` 가 정하므로
   화면이 그 수를 넘겨 준다 — 두 곳에 적어 두면 한쪽만 고쳐진다(CM-24). */
.pipe{grid-template-columns:repeat(var(--n, 3), 1fr)}
@media(max-width:860px){ .pipe{grid-template-columns:repeat(2,1fr)} }

/* 긴 한국어 글이 아무 데서나 끊기지 않게.
   `Coolify 가 그 앱을...` 같은 줄이 낱말 가운데서 꺾여 읽기 어려웠다 —
   한국어는 낱말 단위로 끊는 것이 맞다. */
.note, .flash, .ibquote, .pstep .at{word-break:keep-all; overflow-wrap:anywhere}

/* ── 올려 둔 파일 한 줄 (올리기 · 자산 관리) ──────────────────
   설치 파일과 가이드 문서는 그림처럼 미리 보여 줄 것이 없다. 이름과
   크기, 그리고 빼는 단추 — 한 줄이면 충분하다.
   **배경에 그냥 놓지 않는다**: 카드 안의 한 칸으로 세운다. */
.upfile{
  display:flex; align-items:center; gap:10px;
  padding:11px 13px; border:1px solid var(--line); border-radius:var(--r-s);
  background:var(--n-50);
}
.upfile > b{flex:1 1 auto; min-width:0; font-size:var(--t-small);
            overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.upfile .fic{
  flex:none; padding:2px 7px; border-radius:4px;
  background:var(--n-100); color:var(--dim); font-size:11px; font-weight:700;
}
.upfile .sz{flex:none; color:var(--dim); font-size:12px}
.upfile .btn{flex:none}

/* 끌어다 놓는 판 아래의 올리기 단추 한 줄.
   `gdrow gdsend` 를 썼더니 76px + 1fr 격자에 들어가 **단추가 통째로
   늘어났다.** 여기는 단추 하나를 오른쪽에 두는 자리다. */
.upact{display:flex; justify-content:flex-end; margin-top:10px}

/* 끌어다 놓은 파일 이름 — 판 안에 한 줄로 적는다.
   놓았는데 아무 것도 안 바뀌면 안 된 줄로 읽힌다. */
.drop .picked{
  display:block; margin-top:8px; padding-top:8px;
  border-top:1px solid var(--line);
  font-size:12px; font-weight:700; color:var(--n-900);
}
.drop.busy{border-color:var(--accent); background:var(--accent-bg); cursor:progress}

/* ── ⓘ 말풍선이 판에 잘리던 것 ────────────────────────────────
   `.spec-card` 에 `overflow:hidden` 이 있었다 — 모난 칸 배경을 둥근
   테두리로 잘라 내려고. 그 바람에 **말풍선이 판을 넘는 순간 잘려 나갔다**:
   첫 줄만 보이고 나머지가 사라지고, 잘린 자리에 스크롤이 생겼다.

   처음엔 아래 줄에서 위로 펼치게 해 봤는데, 줄이 한두 개뿐인 판(설치
   파일 · 사용자 가이드)에서는 **위에도 자리가 없었다.** 어느 쪽으로
   펼쳐도 판 안에서는 안 된다 — 잘라 내기를 끄는 것이 답이다.

   대신 모서리는 **칸이 스스로** 둥글린다. 첫 줄과 마지막 줄의 왼쪽
   칸만 둥글리면 된다 — 배경이 있는 것은 그 칸뿐이다. */
.spec-card{overflow:visible}
.spec-card > .form > .frow2:first-child > .lb{border-top-left-radius:var(--r)}
.spec-card > .form > .frow2:last-child  > .lb{border-bottom-left-radius:var(--r)}
.spec-card > .spec > dt:first-of-type{border-top-left-radius:var(--r)}
.spec-card > .spec > dt:last-of-type{border-bottom-left-radius:var(--r)}

/* ── 상세 머리의 담당자 줄 ────────────────────────────────────
   역할을 사람마다 찍었더니 `PO 이재은 PO 이선희` 가 되어 둘이 같은
   역할인지 역할이 둘인지 읽히지 않았다. 역할 하나에 사람을 묶고,
   묶음끼리는 넉넉히 띄운다. */
.dhead .who{display:flex; flex-wrap:wrap; gap:6px 20px; align-items:baseline}
.dhead .who .wgrp{display:inline-flex; align-items:baseline; gap:6px}
.dhead .who .wgrp .k{
  flex:none; padding:1px 7px; border-radius:4px;
  background:var(--n-100); color:var(--dim);
  font-size:11px; font-weight:700; letter-spacing:0;
}
.dhead .who .wgrp b{font-weight:700; color:var(--n-900)}
/* 사람은 `이름·부서` 한 덩이다. 사람과 사람 사이는 점이 아니라 **사이를
   띄워** 가른다(`.wgrp` 의 gap) — 점으로 가르면 이름과 부서를 잇는 점과
   구별되지 않는다. 상세는 한 줄이라 접지 않고 그대로 늘어놓는다 */
.dhead .who .wgrp .p{display:inline-flex; align-items:baseline}
.dhead .who .wgrp .p .d{color:var(--dim); font-weight:400}

/* ── 카드의 담당자 줄 (목업 `owners(a,'card')`) ───────────────
   **역할마다 제 줄이다.** 한 줄에 나란히 흘리면 어디까지가 PO 인지 읽히지
   않는다 — flex 로 두었더니 `PO 서혁기 이덕호 기술 담당 장호중` 이 한 줄로
   붙어 나왔다(2026-09-18). 왼쪽 칸이 역할, 오른쪽 칸이 사람이다.

   사람은 `이름·부서`. 사람과 사람 사이는 점이 아니라 **사이를 띄워** 가른다 —
   점으로 가르면 이름과 부서를 잇는 점과 구별되지 않는다.

   한 줄을 넘기면 자른다. 카드는 줄 수가 정해져 있어(아랫단을 맞춘다) 넘치면
   접히는 대신 카드가 길어진다. */
.acard .own{
  display:grid; grid-template-columns:auto 1fr; gap:4px 8px; align-items:baseline;
  margin-top:10px; font-size:12px; color:var(--dim);
}
/* 알약은 **칸을 꽉 채우고 글자는 가운데**다. 칸 너비는 넓은 쪽
   (`기술 담당`)이 정하는데, 짧은 `PO` 를 왼쪽에 붙여 두면 알약 둘의
   크기가 달라 줄이 어긋나 보인다 */
.acard .own .k{
  justify-self:stretch; text-align:center;
  padding:1px 6px; border-radius:4px;
  background:var(--n-100); color:var(--dim); font-size:11px; font-weight:700;
}
.acard .own .nm{
  min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.acard .own .p + .p{margin-left:10px}
.acard .own .p b{color:var(--n-900); font-weight:700}
.acard .own .p .d{color:var(--dim); font-weight:400}
/* 아직 없는 줄. 자리는 두되 글자는 흐리게 — 비어 있다는 것도 사실이다 */
.acard .own .none{color:var(--n-300)}

/* ── 좁혀 보기 판을 낮춘다 ───────────────────────────────────
   찾는 칸이 판 밖에 따로 떠서 높이 70px(46 + 여백 24)을 혼자 먹었고,
   줄마다 12px 여백 + 12px 윗여백 + 테두리라 판이 목록을 밀어냈다.
   찾는 칸을 판 안으로 들이고 줄 사이를 좁힌다. */
.filters{padding:12px 16px; gap:8px}
.frow + .frow{padding-top:8px}
/* 판 안의 찾는 칸 — 밖에 있던 `.sbox-l` 보다 낮게. 한 줄 높이에 맞춘다 */
.fsrch{
  flex:1 1 260px; min-width:0; display:flex; align-items:center; gap:8px;
  height:32px; padding:0 11px;
  border:1px solid var(--line-strong); border-radius:var(--r-s);
  background:var(--surface);
}
.fsrch:focus-within{border-color:var(--accent); outline:2px solid var(--focus-ring);
                    outline-offset:1px}
.fsrch svg{width:15px; height:15px; color:var(--dim); flex:none}
.fsrch input{
  flex:1; min-width:0; border:0; outline:0; background:none;
  font:inherit; font-size:var(--t-small);
}
.fsrch input::placeholder{color:var(--faint)}

/* ── Q&A 의 답 한 덩어리 ─────────────────────────────────────
   물어본 것 아래에 답을 펼쳐 둔다. 감춰 두면 제목만 남아 무엇이 답인지
   알 수 없다. 답임을 알리는 표를 왼쪽에 둔다. */
.qans{
  display:flex; gap:9px; margin-top:9px; padding:10px 12px;
  border-radius:var(--r-s); background:var(--n-50);
  border-left:2px solid var(--accent);
}
.qans .k{
  flex:none; padding:1px 7px; border-radius:4px; height:fit-content;
  background:var(--accent-bg); color:var(--accent-ink);
  font-size:11px; font-weight:700;
}
.qans p{margin:0; font-size:var(--t-small); color:var(--ink)}
.qans .d{display:block; margin-top:5px; font-size:12px; color:var(--dim)}

/* ── Q&A ─────────────────────────────────────────────────────
   답 한 덩어리. **고른 답은 눈에 띄어야 한다** — 뒤에 온 사람이
   "무엇이 답이었나" 를 바로 찾는 것이 이 화면의 쓸모다. */
.qbody{padding:18px 20px; font-size:var(--t-small); line-height:1.75}
.qa1{padding:14px 16px; margin-top:10px}
.qa1.picked{border-color:var(--ok); background:var(--ok-bg)}
.qa1 .qah{
  display:flex; align-items:center; gap:8px; flex-wrap:wrap;
  margin:0 0 8px; font-size:var(--t-small);
}
.qa1 .qah b{color:var(--n-900)}
.qa1 .qah .num{color:var(--dim); font-size:12px}
.qa1 .qat{font-size:var(--t-small); line-height:1.75; color:var(--ink)}
/* 쪽 넘기기 */
.pager{
  display:flex; align-items:center; gap:10px;
  padding:12px 16px; border-top:1px solid var(--n-100);
}
.pager .pnow{font-size:12px; font-weight:700; color:var(--dim);
             font-variant-numeric:tabular-nums}
.pager .spacer{flex:1}

/* ── 좁혀 보기를 기둥으로 세운다 ─────────────────────────────
   `margin-left:auto` 로 오른쪽 묶음을 밀었더니 줄마다 제 오른쪽 끝에
   붙어, `상태` 와 `정렬` 이 서로 다른 자리에 섰다. **맞춰야 할 것은
   가장자리가 아니라 기둥이다.**

   줄을 `display:contents` 로 풀어 판 하나가 격자를 갖는다 — 그래야
   줄이 달라도 같은 기둥에 선다. 기둥 넷:

       이름 | 칩 | 오른쪽 이름 | 오른쪽 칩
       찾기 | 찾는 칸 ─────────────────→ (끝까지)
       분류 | …      | 상태 | …
   공개범위 | …      | 정렬 | …

   **남는 폭은 마지막 기둥이 받는다.** 왼쪽 칩 기둥을 `1fr` 로 두었더니
   그 기둥이 남는 폭을 다 먹어 `분류` 칩과 `상태` 사이가 손바닥만큼
   벌어졌다(2026-09-17). 왼쪽 칩은 제 글자만큼만(`max-content`) 쓰고,
   남는 폭은 오른쪽 칩 기둥이 받되 칩은 그 안에서 왼쪽에 붙는다 —
   그래야 오른쪽 묶음이 왼쪽 묶음 바로 옆에 선다.

   **기둥을 다섯으로 늘리지 않는다.** `display:contents` 라 줄이라는
   것이 없다 — 칸이 차례로 흘러 들어가므로, 기둥 수가 한 줄의 칸 수와
   어긋나면 다음 줄 첫 칸이 앞 줄 끝에 붙어 버린다. */
.filters.cols{
  display:grid; align-items:center;
  grid-template-columns:56px max-content max-content minmax(max-content, 1fr);
  gap:8px 12px;
}
.filters.cols > .frow{display:contents}
/* 찾는 칸은 둘째 기둥부터 끝까지 */
.filters.cols .wide{
  grid-column:2 / -1; display:flex; align-items:center; gap:10px;
}
/* 오른쪽 이름은 제 기둥 안에서 칩 바로 앞에 붙는다 */
.filters.cols .flab.rt{width:auto; margin-left:18px}

/* 좁은 화면에서는 기둥을 접는다 — 네 기둥을 그대로 두면 칩이 한 글자씩
   끊긴다. 이름과 칩 둘로만 세운다 */
@media(max-width:860px){
  .filters.cols{grid-template-columns:56px minmax(0, 1fr)}
  .filters.cols .flab.rt{margin-left:0}
}

/* 지표 한 칸이 두 칸을 쓴다 — 스킬명은 `gabia-billing-pumi` 처럼 길어
   한 칸에 넣으면 가운데서 끊긴다(목업 `skill.html` 의 `sum .wide`). */
.sum .wide{grid-column:span 2; min-width:0}
@media(max-width:860px){ .sum .wide{grid-column:span 2} }

/* 판 안의 글칸과 단추 줄 — 로그인 판(`.lgmodal`)이 제 옷을 입고 있어
   그 밖의 판은 여기서 입힌다. */
.modal > .who{margin:4px 0 16px; font-size:var(--t-small); color:var(--dim)}
.modal label{display:block; margin-bottom:8px; font-size:var(--t-small);
             font-weight:700; color:var(--n-900)}
.modal textarea{
  width:100%; padding:10px 12px; border:1px solid var(--line);
  border-radius:var(--r-s); font:inherit; font-size:var(--t-small);
  line-height:1.7; resize:vertical; background:var(--surface);
}
.modal textarea:focus{outline:0; border-color:var(--accent)}
.modal .mf{display:flex; justify-content:flex-end; gap:8px; margin-top:18px}
