/* ═══ ReqHub 앱 레이어 — 와이어프레임에 없던 실동작 요소 ═══ */

html,body{height:100%}
body{background:var(--paper)}
a{color:inherit}
:focus-visible{outline:2px solid var(--blue);outline-offset:2px;border-radius:2px}
.btn:focus-visible,.tabs button:focus-visible{outline-offset:1px}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}

/* ─── 브랜드 (minijoy 심볼) ───────────────────────── */
.brand{cursor:pointer;text-decoration:none}
.brand .glyph{border:0;width:26px;height:26px;padding:0}
.brand .glyph svg{width:26px;height:22px;display:block}
.brand small{display:block;font-family:var(--mono);font-size:8.5px;letter-spacing:.14em;color:var(--mute);text-transform:uppercase}

/* ─── 인증 화면 ───────────────────────────────────── */
.auth-wrap{min-height:100vh;display:grid;place-items:center;padding:24px;background:var(--paper)}
.auth-card{width:min(420px,100%);background:var(--surface);border:1px solid var(--line);border-radius:var(--r);overflow:hidden}
.auth-head{padding:24px 24px 18px;border-bottom:1px solid var(--line-soft)}
.auth-head .mark{display:flex;align-items:center;gap:10px;margin-bottom:14px}
.auth-head .mark svg{width:38px;height:31px}
.auth-head .mark strong{font-size:19px;letter-spacing:-.02em}
.auth-head .mark small{display:block;font-family:var(--mono);font-size:9px;letter-spacing:.14em;color:var(--mute);text-transform:uppercase}
.auth-head h1{margin:0;font-size:16px;letter-spacing:-.01em}
.auth-head p{margin:5px 0 0;font-size:12.5px;color:var(--mute);line-height:1.55}
.auth-body{padding:20px 24px 24px}
.auth-foot{padding:13px 24px;background:var(--surface-2);border-top:1px solid var(--line-soft);font-size:12px;color:var(--mute);display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.auth-foot button{border:0;background:transparent;color:var(--blue);font-size:12px;text-decoration:underline;padding:0}
.auth-tabs{display:flex;gap:2px;margin-bottom:16px;border-bottom:1px solid var(--line)}
.auth-tabs button{border:1px solid transparent;border-bottom:0;background:transparent;padding:7px 13px;font-size:12.5px;color:var(--mute);border-radius:var(--r) var(--r) 0 0;margin-bottom:-1px}
.auth-tabs button[aria-selected="true"]{background:var(--surface);border-color:var(--line);color:var(--ink);font-weight:600}

.alert{border-left:2px solid var(--mark);background:var(--mark-soft);padding:9px 12px;border-radius:0 var(--r) var(--r) 0;font-size:12.5px;color:#5f3323;margin-bottom:14px;line-height:1.5}
.alert.ok{border-color:var(--ok);background:var(--ok-soft);color:#2c5138}
.alert.info{border-color:var(--blue);background:var(--blue-soft);color:#2a4272}
.alert.warn{border-color:var(--warn);background:var(--warn-soft);color:#6b5216}

/* ─── 사이드바: 로그인 칩 ─────────────────────────── */
.side-foot{position:relative;cursor:pointer}
.side-foot:hover{background:var(--surface)}
.side-foot .caret{margin-left:auto;color:var(--mute);font-size:10px}
.usermenu{position:absolute;bottom:calc(100% + 6px);left:10px;right:10px;background:var(--surface);border:1px solid var(--ink);border-radius:var(--r);z-index:70;overflow:hidden;box-shadow:0 6px 22px rgba(20,20,22,.14)}
.usermenu button{display:flex;align-items:center;gap:8px;width:100%;border:0;background:transparent;padding:9px 12px;font-size:12.5px;text-align:left;border-bottom:1px solid var(--line-soft)}
.usermenu button:last-child{border-bottom:0}
.usermenu button:hover{background:var(--surface-2)}
.usermenu .sep{padding:7px 12px;background:var(--surface-2);font-family:var(--mono);font-size:9px;letter-spacing:.02em;text-transform:uppercase;color:var(--mute);border-bottom:1px solid var(--line-soft)}

/* ─── 프로젝트 스위처 ─────────────────────────────── */
.proj-switch{position:relative;cursor:pointer;text-align:left;width:calc(100% - 24px);font:inherit}
.proj-switch:hover{border-color:var(--ink)}
.projmenu{position:absolute;top:calc(100% + 5px);left:0;right:0;background:var(--surface);border:1px solid var(--ink);border-radius:var(--r);z-index:70;max-height:290px;overflow:auto;box-shadow:0 6px 22px rgba(20,20,22,.14)}
.projmenu button{display:block;width:100%;border:0;background:transparent;padding:9px 12px;font-size:12.5px;text-align:left;border-bottom:1px solid var(--line-soft)}
.projmenu button:hover{background:var(--surface-2)}
.projmenu button.on{background:var(--blue-soft)}
.projmenu button small{display:block;font-family:var(--mono);font-size:9.5px;color:var(--mute);margin-top:1px}

/* ─── 알림 드롭다운 ───────────────────────────────── */
.bell{position:relative}
.bell .dotn{position:absolute;top:-4px;right:-5px;min-width:15px;height:15px;padding:0 3px;border-radius:9px;background:var(--mark);color:#fff;font-family:var(--mono);font-size:9px;display:grid;place-items:center;line-height:1}
.notif-pop{position:absolute;top:calc(100% + 8px);right:0;width:min(340px,84vw);background:var(--surface);border:1px solid var(--ink);border-radius:var(--r);z-index:70;max-height:400px;overflow:auto;box-shadow:0 8px 26px rgba(20,20,22,.16)}
.notif-pop .h{position:sticky;top:0;background:var(--surface-2);padding:9px 12px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:8px;font-size:12px;font-weight:600}
.notif-pop .h .acts{margin-left:auto}
.notif-item{display:block;width:100%;text-align:left;border:0;background:transparent;padding:10px 12px;border-bottom:1px solid var(--line-soft);font-size:12.5px;line-height:1.5}
.notif-item:hover{background:var(--surface-2)}
.notif-item.unread{background:var(--blue-soft)}
.notif-item.unread:hover{background:#dae1f0}
.notif-item b{display:block;font-size:12.5px;margin-bottom:2px}
.notif-item span{color:var(--mute);font-size:11.5px;display:block}
.notif-item time{font-family:var(--mono);font-size:10px;color:var(--mute);display:block;margin-top:3px}

/* ─── 토스트 ──────────────────────────────────────── */
.toasts{position:fixed;right:16px;bottom:16px;z-index:200;display:flex;flex-direction:column;gap:8px;max-width:min(380px,90vw)}
.toast{background:var(--ink);color:#f2f1ee;border-radius:var(--r);padding:11px 14px;font-size:12.5px;line-height:1.5;display:flex;gap:9px;align-items:flex-start;box-shadow:0 6px 22px rgba(20,20,22,.24);animation:tin .18s ease}
.toast.ok{background:#2f5a3d}
.toast.err{background:#8a3a20}
.toast .x{margin-left:auto;border:0;background:transparent;color:inherit;opacity:.6;font-size:14px;line-height:1;padding:0}
.toast .x:hover{opacity:1}
@keyframes tin{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}

/* ─── 빈 상태 · 로딩 · 에러 ───────────────────────── */
.empty{border:1px dashed var(--line);border-radius:var(--r);padding:40px 20px;text-align:center;color:var(--mute);font-size:13px;background:var(--surface-2)}
.empty b{display:block;color:var(--ink);font-size:14px;margin-bottom:5px}
.empty > span{display:block;max-width:46ch;margin:0 auto}
.empty .btn{display:inline-block;margin-top:14px}
.skeleton{border:1px solid var(--line-soft);border-radius:var(--r);height:56px;margin-bottom:8px;background:linear-gradient(90deg,var(--surface-2) 25%,#eeede9 50%,var(--surface-2) 75%);background-size:200% 100%;animation:sk 1.2s linear infinite}
@keyframes sk{from{background-position:200% 0}to{background-position:-200% 0}}
.spin{display:inline-block;width:13px;height:13px;border:2px solid var(--line);border-top-color:var(--ink);border-radius:50%;animation:sp .7s linear infinite;vertical-align:-2px}
@keyframes sp{to{transform:rotate(360deg)}}

/* ─── 표 · 목록 보강 ──────────────────────────────── */
.table tbody tr.sel{background:var(--blue-soft)}
.table td .bar{display:inline-block;width:56px;flex:none;vertical-align:middle}
.table-wrap{overflow-x:auto}
.chip.btnlike{cursor:pointer;border:0;font:inherit;font-family:var(--mono);font-size:11px}
.chip.btnlike:hover{border-color:var(--ink)}
.chip.on{background:var(--ink);color:#fff;border-color:var(--ink)}
.chip.on::before{background:#fff}
.filterbar{display:flex;gap:6px;flex-wrap:wrap;align-items:center;margin-bottom:12px}
.filterbar select.mini{border:1px solid var(--line);border-radius:20px;padding:3px 8px;font-size:11px;font-family:var(--mono);background:var(--surface);max-width:170px}
.rowlink{cursor:pointer}

/* ─── 진행 보드 ───────────────────────────────────
   상태 전이는 에이전트 세션과 검수 흐름이 주도하므로
   카드를 끌어 옮기는 조작은 제공하지 않는다. */
.tick{cursor:pointer}
.tick:hover{border-color:var(--ink)}

/* ─── 타임라인 ────────────────────────────────────── */
.timeline{position:relative;padding-left:20px}
.timeline::before{content:"";position:absolute;left:5px;top:6px;bottom:6px;width:1px;background:var(--line)}
.tl-item{position:relative;padding:0 0 16px 0}
.tl-item::before{content:"";position:absolute;left:-18px;top:6px;width:9px;height:9px;border-radius:50%;background:var(--surface);border:1.5px solid var(--mute)}
.tl-item.done::before{background:var(--ok);border-color:var(--ok)}
.tl-item.running::before{background:var(--warn);border-color:var(--warn)}
.tl-item .when{font-family:var(--mono);font-size:10.5px;color:var(--mute)}
.tl-item .t{font-size:13px;font-weight:600;margin:1px 0 3px}

/* ─── 완료조건 편집 ───────────────────────────────── */
.ac-edit li{align-items:flex-start;gap:8px}
.ac-edit .inp{flex:1;padding:5px 8px;font-size:12.5px}
.ac-edit .del{border:0;background:transparent;color:var(--mute);padding:3px 5px;font-size:13px;line-height:1;flex:none}
.ac-edit .del:hover{color:var(--mark)}
.ac .note{margin:4px 0 0;padding:5px 9px;font-size:11.5px;background:var(--surface-2);border-left-color:var(--line);color:var(--mute)}

/* ─── 리포트 좌우 대조 ────────────────────────────── */
.split-b.scroll-sync{max-height:none}
.ac li.hidden-diff{display:none}
.report-frame{width:100%;min-height:520px;border:1px solid var(--line);border-radius:var(--r);background:var(--surface);display:block}
.report-toolbar{display:flex;gap:6px;align-items:center;flex-wrap:wrap;margin-bottom:8px}

/* ─── 첨부 드롭 영역 ──────────────────────────────── */
.drop{cursor:pointer;transition:border-color .15s,background .15s}
.drop:hover,.drop.over{border-color:var(--blue);background:var(--blue-soft);color:var(--blue)}
.file-row .rm{margin-left:6px}
.file-row a{color:var(--blue);text-decoration:none}
.file-row a:hover{text-decoration:underline}

/* ─── 마크다운 렌더 ───────────────────────────────── */
.md{font-size:13px;line-height:1.7}
.md h1,.md h2,.md h3{margin:16px 0 7px;letter-spacing:-.01em}
.md h1{font-size:16px}.md h2{font-size:14.5px}.md h3{font-size:13.5px}
.md h1:first-child,.md h2:first-child,.md h3:first-child{margin-top:0}
.md p{margin:0 0 10px}
.md ul,.md ol{margin:0 0 10px;padding-left:20px}
.md li{margin-bottom:3px}
.md code{font-family:var(--mono);font-size:11.5px;background:var(--surface-2);padding:1px 4px;border-radius:2px}
.md pre{background:var(--surface-2);border:1px solid var(--line-soft);border-radius:var(--r);padding:10px 12px;overflow-x:auto;margin:0 0 10px}
.md pre code{background:transparent;padding:0;font-size:11.5px;line-height:1.6}
.md blockquote{margin:0 0 10px;padding-left:11px;border-left:2px solid var(--line);color:var(--mute)}
.md hr{border:0;border-top:1px solid var(--line-soft);margin:14px 0}
.md a{color:var(--blue)}
.md table{border-collapse:collapse;font-size:12.5px;margin:0 0 10px;width:100%}
.md th,.md td{border:1px solid var(--line-soft);padding:5px 8px;text-align:left}
.md th{background:var(--surface-2);font-weight:600}

/* ─── 모달 보강 ───────────────────────────────────── */
.modal.wide{width:min(680px,100%)}
.modal.xwide{width:min(920px,100%)}
.modal-b .field:last-child{margin-bottom:0}
.modal-bg{animation:fade .14s ease}
@keyframes fade{from{opacity:0}to{opacity:1}}

/* ─── 관리자 ──────────────────────────────────────── */
.admin-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px;margin-bottom:16px}
.code-pill{font-family:var(--mono);font-size:12px;background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r);padding:4px 9px;display:inline-flex;align-items:center;gap:7px}
.code-pill button{border:0;background:transparent;color:var(--mute);font-size:11px;padding:0}
.code-pill button:hover{color:var(--ink)}

/* ─── 세션 로그 ───────────────────────────────────── */
.logbox{font-family:var(--mono);font-size:11.5px;line-height:1.65;background:#1b1c1f;color:#d7d7d2;border-radius:var(--r);padding:12px 14px;max-height:420px;overflow:auto}
/* 명령이 아니라 '세션에 시킬 말' 을 담은 상자는 접어서 보여준다.
   명령은 줄이 바뀌면 뜻이 달라질 수 있어 그대로 두고 옆으로 밀어 본다. */
/* 한글은 글자마다 줄을 바꿀 수 있어, 그냥 접으면 '맡아│줘' 처럼 어절이 갈라진다.
   어절은 지키고, 어절 하나가 칸보다 길 때만 자른다. */
.logbox.wrap{white-space:pre-wrap;word-break:keep-all;overflow-wrap:break-word}
.logbox .t{color:#75766f;margin-right:8px}
.logbox .k{color:#8fb4e8}
.logbox .k.error{color:#e08c72}
.logbox .k.done{color:#8fca9f}
/* 사람이 답해야 하는 줄은 눈에 띄어야 한다 — 로그를 훑다 놓치면 세션이 그대로 서 있는다. */
.logbox .k.question{color:#e8c46a}
.logbox .k.comment{color:#9a9b93}

/* ─── 공유 공개 뷰 ────────────────────────────────── */
.public-wrap{max-width:1080px;margin:0 auto;padding:24px 18px 60px}
.public-head{display:flex;align-items:center;gap:12px;padding-bottom:14px;border-bottom:1px solid var(--line);margin-bottom:18px;flex-wrap:wrap}
.public-head svg{width:32px;height:26px}
.public-head .ro{margin-left:auto}

/* ─── 진행 상세: 실행 현황 ────────────────────────── */
.qbox{border:1px solid var(--blue);background:var(--blue-soft);border-radius:var(--r);padding:11px 13px;margin-top:8px}
.qbox .qh{font-size:11.5px;font-family:var(--mono);color:var(--blue);letter-spacing:.02em;text-transform:uppercase;margin-bottom:6px}
.answered-tag{font-family:var(--mono);font-size:10px;color:var(--ok);border:1px solid var(--ok);border-radius:20px;padding:1px 7px}

/* ─── 유틸 ────────────────────────────────────────── */
.mt0{margin-top:0}.mb0{margin-bottom:0}.mb8{margin-bottom:8px}.mb12{margin-bottom:12px}.mb14{margin-bottom:14px}.mb16{margin-bottom:16px}
.mt8{margin-top:8px}.mt12{margin-top:12px}.mt14{margin-top:14px}
.row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.row.end{justify-content:flex-end}
.push{margin-left:auto}
.muted{color:var(--mute)}
.mono{font-family:var(--mono)}
.nowrap{white-space:nowrap}
.grow{flex:1;min-width:0}
.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.hidden{display:none!important}

@container (max-width: 860px){
  .sidebar{position:absolute;height:100%}
  .detail-grid{grid-template-columns:1fr}
}
@container (max-width: 640px){
  .admin-grid{grid-template-columns:1fr 1fr}
}

/* ─── 시각 검증 반영 보정 ─────────────────────────── */
/* 프로젝트 카드의 상태 칩이 컬럼 폭 전체로 늘어나지 않도록 */
.proj-card > .chip{align-self:flex-start}
/* 진행 스테퍼: 라벨·시각이 한 줄에 붙지 않고 쌓이도록 */
.flow li > span{display:block}
/* 토스트 위치
   · 우상단 = 페이지 액션 버튼(제출·검수 승인 등)이 있는 자리
   · 우하단 = 폼 푸터 버튼(다음 단계·제출하기)이 있는 자리
   두 곳 모두 오른쪽 정렬이므로 좌하단(사이드바 바깥)에 띄운다. */
.toasts{left:232px;right:auto;bottom:18px;top:auto;align-items:flex-start}

/* ─── 클릭 타겟 최소 크기 (UX 감사 반영) ─────────── */
/* 프로젝트 카드 ⋯ 메뉴 */
.proj-card .menu{min-width:28px;min-height:28px;display:grid;place-items:center;border-radius:var(--r);margin:-4px -4px 0 0}
.proj-card .menu:hover{background:var(--surface-2);color:var(--ink)}
/* 초대 코드 복사 버튼 */
.code-pill button{min-width:30px;min-height:24px;padding:2px 6px;border-radius:2px}
.code-pill button:hover{background:var(--line-soft)}
/* 인증 화면 텍스트 링크 */
.auth-foot button{min-height:26px;padding:4px 2px}
/* 상태 칩 버튼 */
.chip.btnlike{min-height:24px;padding:3px 10px}
/* 댓글·목록의 ghost 버튼 */
.btn.sm.ghost{min-height:24px}

/* 표 셀 안의 인라인 select 는 내용 폭에 맞춘다 */
.table td select.inp{width:auto;min-width:104px;max-width:100%}

/* ─── 첨부 이미지 썸네일 ─────────────────────────── */
.att-thumb{display:block;width:100%;padding:0;margin-top:7px;border:1px solid var(--line-soft);border-radius:var(--r);overflow:hidden;background:var(--surface-2);cursor:zoom-in}
.att-thumb:hover{border-color:var(--ink)}
.att-thumb img{display:block;width:100%;max-height:150px;object-fit:cover}

/* ─── 장문·긴 문자열 오버플로 방지 ────────────────
   grid/flex 자식은 기본 min-width:auto 라서 끊기지 않는 긴 문자열이
   트랙을 밀어낸다. min-width:0 으로 트랙 폭을 고정하고,
   텍스트 블록은 필요할 때만 줄바꿈되도록 overflow-wrap:break-word 를 준다.

   anywhere 가 아니라 break-word 인 이유: anywhere 는 자리가 모자라면
   단어 한가운데를 끊는다. 한글은 그러면 "프로젝" / "트" 처럼 갈라진다.
   break-word 는 그 단어가 한 줄에 통째로 못 들어갈 때만 끊는다. */
.detail-grid > *,
.grid-2 > *, .grid-3 > *,
.two > *, .three > *,
.board > *, .board-col > *,
.split > section,
.admin-grid > *,
.page-h > *, .card-h > *, .row > *,
.form-foot > *, .filterbar > * { min-width: 0 }

.md, .md p, .md li, .md h1, .md h2, .md h3, .md blockquote,
.ac li, .ac li span,
.page-h h1, .page-h p,
.card-b, .split-b,
.table td, .table .ttl,
.proj-card h3, .proj-card .desc,
.tick .t, .tl-item .t,
.cmt p, .cmt .bd,
.notif-item, .notif-item b, .notif-item span,
.empty, .alert, .note > div,
.kv dd, .file-row, .diffbox .path,
.toast { overflow-wrap: break-word }

/* 코드·경로처럼 공백이 없는 문자열은 확실히 끊는다 */
.md code, .md pre, .inp.mono, .diffbox, .logbox,
.kv dd.mono, .code-pill { overflow-wrap: anywhere; word-break: break-all }
.md pre { overflow-x: auto }

/* 표는 자체 스크롤 컨테이너를 갖는다 */
.table-wrap { max-width: 100% }

/* 사이드바가 서랍으로 바뀌는 폭에서는 토스트를 화면 좌하단에 붙인다 */
@media (max-width: 900px){
  .toasts{left:12px;right:12px;max-width:none}
}

/* ─── Claude 질문의 선택지 ────────────────────────
   선택지는 한 줄짜리 라벨일 수도, 근거를 담은 긴 문장일 수도 있다.
   잘리면 무엇을 고르는지 알 수 없으므로 줄바꿈을 허용한다. */
.qbox .choices{display:flex;flex-direction:column;gap:6px;align-items:stretch}
.qbox .choices .btn{
  white-space:normal;text-align:left;line-height:1.5;padding:8px 11px;
  overflow-wrap:break-word;
}
.qbox .choices .btn .num{
  font-family:var(--mono);font-size:10px;opacity:.65;margin-right:7px;
}
.qbox .choices .btn.ghost{align-self:flex-start;white-space:nowrap}

/* ─── 멤버 초대 후보 ──────────────────────────────
   동명이인이 흔하므로 아이디가 항상 보여야 하고, 선택이 눈에 띄어야 한다. */
.file-row.cand.on{border-color:var(--ink);background:var(--blue-soft)}
.file-row.cand:hover{border-color:var(--line)}

/* ─── 요구사항 스택 ───────────────────────────────
   상태별로 쌓아 보여준다. 지금 손이 필요한 것이 맨 위. */
.stack{margin-bottom:20px}
.stack-h{display:flex;align-items:baseline;gap:9px;margin-bottom:8px;flex-wrap:wrap}
.stack-h h2{margin:0;font-size:14px;letter-spacing:-.01em}
.stack-h .ct{font-family:var(--mono);font-size:11px;color:var(--mute);
  border:1px solid var(--line);border-radius:20px;padding:0 7px}
.stack.urgent .stack-h h2{color:var(--mark)}
.stack.urgent .stack-h .ct{border-color:var(--mark);color:var(--mark)}
.stack-b{border:1px solid var(--line);border-radius:var(--r);overflow:hidden;background:var(--surface)}
.stack.urgent .stack-b{border-color:var(--mark)}

.req-row{display:flex;align-items:center;gap:12px;padding:11px 13px;
  border-bottom:1px solid var(--line-soft);cursor:pointer;font-size:13px}
.req-row:last-child{border-bottom:0}
.req-row:hover{background:var(--surface-2)}
.req-row .id{font-size:11px;color:var(--mute);flex:none;min-width:62px}
.req-row .ttl{font-weight:600;min-width:0;overflow-wrap:break-word}
.req-row .who{display:flex;align-items:center;gap:6px;flex:none;color:var(--mute);font-size:12px}
.req-row .when{flex:none;font-size:10.5px;color:var(--mute);min-width:52px;text-align:right}

@container (max-width: 640px){
  .req-row{gap:8px;padding:10px}
  .req-row .id{min-width:0}
}

/* ─── 접어둔 부가 정보 ────────────────────────────── */
details.card > summary::-webkit-details-marker{display:none}
details.card > summary::after{content:"펼치기";margin-left:auto;font-family:var(--mono);
  font-size:10px;letter-spacing:.02em;text-transform:uppercase;color:var(--mute)}
details.card[open] > summary::after{content:"접기"}
details.card > summary:hover{background:var(--surface-2)}

/* ─── 아이콘 ──────────────────────────────────────
   글자 옆에 놓아도 기준선이 흔들리지 않게. */
.ic-svg{display:inline-block;vertical-align:-.18em;flex:none}
.btn .ic-svg{margin-right:5px;margin-left:-1px}
.btn.icon-only{padding:6px 8px}
.btn.icon-only .ic-svg{margin:0}

/* ═══ 움직임 ═══════════════════════════════════════
   화면이 바뀔 때 무엇이 어디로 갔는지 눈이 따라갈 수 있게.
   짧고 작게 — 기다리게 만들면 그게 더 지루하다. */

/* 버튼: 눌리는 감각 */
.btn{transition:background var(--t-fast) var(--ease),border-color var(--t-fast) var(--ease),
  color var(--t-fast) var(--ease),transform var(--t-fast) var(--ease),box-shadow var(--t-fast) var(--ease)}
.btn:hover:not(:disabled){transform:translateY(-1px);box-shadow:var(--shadow-sm)}
.btn:active:not(:disabled){transform:translateY(0);box-shadow:none}
.btn.primary:hover:not(:disabled){background:var(--pine)}
.btn.blue:hover:not(:disabled){background:var(--leaf-deep)}

/* 목록의 줄: 훑을 때 지금 어디를 보는지 */
.req-row{transition:background var(--t-fast) var(--ease),padding-left var(--t-fast) var(--ease)}
.req-row::before{content:"";position:absolute;left:0;top:0;bottom:0;width:2px;
  background:var(--leaf);transform:scaleY(0);transform-origin:center;transition:transform var(--t) var(--ease)}
.req-row{position:relative}
.req-row:hover{padding-left:16px}
.req-row:hover::before{transform:scaleY(1)}

/* 카드: 떠오르는 정도만 */
.proj-card{transition:border-color var(--t) var(--ease),box-shadow var(--t) var(--ease),transform var(--t) var(--ease)}
.proj-card:hover{transform:translateY(-2px);box-shadow:var(--shadow)}
.stat.rowlink:hover{border-color:var(--leaf);box-shadow:var(--shadow-sm)}

/* 화면이 들어올 때 */
.body > *{animation:rise var(--t) var(--ease) both}
.body > *:nth-child(2){animation-delay:.03s}
.body > *:nth-child(3){animation-delay:.06s}
.body > *:nth-child(n+4){animation-delay:.09s}
@keyframes rise{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}

/* 스택 그룹이 순서대로 */
.stack{animation:rise var(--t) var(--ease) both}
.stack:nth-of-type(2){animation-delay:.04s}
.stack:nth-of-type(3){animation-delay:.08s}
.stack:nth-of-type(n+4){animation-delay:.12s}

/* 모달 */
.modal{animation:pop .18s var(--ease) both}
@keyframes pop{from{opacity:0;transform:translateY(8px) scale(.985)}to{opacity:1;transform:none}}

/* 진행바가 차오르는 것 */
.bar i{transition:width .6s var(--ease)}

/* 지금 진행 중인 것은 살아 있어 보이게 */
.chip.running::before{animation:pulse 1.6s ease-in-out infinite}
.stack[data-group="running"] .bar i{
  background:linear-gradient(90deg,var(--leaf),var(--coral),var(--leaf));
  background-size:200% 100%;animation:flow 2.4s linear infinite}
@keyframes flow{to{background-position:-200% 0}}

/* 손이 필요한 묶음은 눈에 먼저 */
.stack.urgent .stack-b{box-shadow:0 0 0 3px var(--coral-soft)}

/* 입력에 초점이 갈 때 */
.inp,textarea.inp,select.inp{transition:border-color var(--t-fast) var(--ease),box-shadow var(--t-fast) var(--ease)}

/* 사이드바 현재 위치 */
.nav a{transition:background var(--t-fast) var(--ease),border-color var(--t-fast) var(--ease),
  padding-left var(--t-fast) var(--ease)}
.nav a:hover{padding-left:12px}
.nav a.on .dot{background:var(--leaf);border-color:var(--leaf);box-shadow:0 0 0 3px var(--leaf-soft)}

/* 아이콘은 부모 색을 따라 함께 변한다 */
.ic-svg{transition:color var(--t-fast) var(--ease),transform var(--t-fast) var(--ease)}
.btn:hover .ic-svg{transform:scale(1.06)}

/* 움직임을 줄여달라고 한 사람에게는 전부 끈다 */
@media (prefers-reduced-motion:reduce){
  .body > *,.stack,.modal{animation:none}
  .btn:hover:not(:disabled),.proj-card:hover{transform:none}
  .req-row:hover{padding-left:13px}
  .nav a:hover{padding-left:9px}
}

/* 목록의 진행 표시 — 막대가 보일 만큼은 넓게 */
.req-row .prog{display:flex;align-items:center;gap:7px;flex:none;min-width:96px;justify-content:flex-end}
.req-row .prog .bar{width:64px;flex:none}
.req-row .prog .mono{font-size:10.5px;color:var(--mute);min-width:30px;text-align:right}
.req-row .chip{flex:none}

/* ═══ 로그인 화면 ═══════════════════════════════════
   처음 만나는 화면이다. 비어 보이지 않게, 그러나 시끄럽지 않게. */
.auth-wrap{position:relative;overflow:hidden}
/* 심볼의 두 색을 아주 옅게 깔아 종이에 번진 것처럼 */
.auth-wrap::before,.auth-wrap::after{
  content:"";position:absolute;border-radius:50%;filter:blur(70px);pointer-events:none;
}
.auth-wrap::before{
  width:46vmax;height:46vmax;left:-16vmax;top:-18vmax;
  background:var(--coral);opacity:.13;
  animation:drift 26s ease-in-out infinite alternate;
}
.auth-wrap::after{
  width:42vmax;height:42vmax;right:-14vmax;bottom:-16vmax;
  background:var(--leaf);opacity:.11;
  animation:drift 32s ease-in-out infinite alternate-reverse;
}
@keyframes drift{
  from{transform:translate3d(0,0,0) scale(1)}
  to{transform:translate3d(3vmax,2vmax,0) scale(1.09)}
}

.auth-card{
  position:relative;border-radius:var(--r-lg);box-shadow:var(--shadow-lg);
  animation:rise .3s var(--ease) both;
}
.auth-head{border-bottom:1px solid var(--line-soft)}
.auth-body .btn.primary{width:100%;padding:10px;border-radius:var(--r)}

/* 마크: 눈이 뜨고 입이 그려진다 */
.mark-draw .eye{transform-origin:center;animation:blinkIn .42s var(--ease) both}
.mark-draw .eye-r{animation-delay:.09s}
.mark-draw .smile{
  stroke-dasharray:120;stroke-dashoffset:120;
  animation:drawSmile .6s var(--ease) .2s forwards;
}
@keyframes blinkIn{from{transform:scale(.2);opacity:0}to{transform:scale(1);opacity:1}}
@keyframes drawSmile{to{stroke-dashoffset:0}}

@media (prefers-reduced-motion:reduce){
  .auth-wrap::before,.auth-wrap::after{animation:none}
  .auth-card{animation:none}
  .mark-draw .eye{animation:none}
  .mark-draw .smile{stroke-dashoffset:0;animation:none}
}

/* ═══ 브랜드: 제품 마크 · 만든 곳 표기 ═════════════════
   좌상단은 제품(AI.Go), 화면 아래는 만든 곳(min2joy). */
.brand{gap:9px}
.brand .prod-mark{transition:transform var(--t) var(--ease)}
.brand .prod-mark svg{border-radius:22%;box-shadow:var(--shadow-sm)}
.brand:hover .prod-mark{transform:translateY(-1px) rotate(-4deg)}
.brand-txt{min-width:0}
.brand-txt strong{display:block;font-size:13.5px;letter-spacing:-.012em;line-height:1.25;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.brand-txt small{display:block;font-size:10.5px;color:var(--mute);line-height:1.4;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;letter-spacing:0;text-transform:none;font-family:var(--sans)}

/* 허브 노드가 숨 쉬듯 천천히 뜬다 */
.prod-spin .pm-card{animation:pmDrop .5s var(--ease) both}
.prod-spin .pm-arrow{animation:pmPush .5s var(--ease) .1s both}
.prod-spin .pm-tray{stroke-dasharray:150;animation:pmDraw .55s var(--ease) .18s both}
@keyframes pmDrop{from{transform:translateY(-12px);opacity:0}to{transform:none;opacity:1}}
@keyframes pmPush{0%{transform:translateY(-8px);opacity:0}60%{transform:translateY(2px);opacity:1}100%{transform:none;opacity:1}}
@keyframes pmDraw{from{stroke-dashoffset:150}to{stroke-dashoffset:0}}
@media (prefers-reduced-motion:reduce){
  .prod-spin .pm-card,.prod-spin .pm-arrow,.prod-spin .pm-tray{animation:none}
  .prod-spin .pm-tray{stroke-dashoffset:0}
}

.made-by{
  display:flex;align-items:center;gap:8px;padding:10px 14px 12px;
  border-top:1px solid var(--line-soft);color:var(--mute);
}
.made-by .mark-svg{flex:0 0 auto;opacity:.9}
.made-by-txt{min-width:0;line-height:1.35}
.made-by-txt strong{display:block;font-size:11.5px;font-weight:600;color:var(--ink);letter-spacing:-.01em}
.made-by-txt span{display:block;font-size:10px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* 실행 중인 버전. 저작권 바로 위에 조용히 붙인다 — 찾을 때만 보이면 된다. */
.sidebar .ver{
  padding:0 14px 6px;font-size:10px;color:var(--mute);opacity:.7;
  font-variant-numeric:tabular-nums;letter-spacing:.02em;
}

/* 로그인·공유 화면에서는 카드 아래 가운데에 놓는다 */
.made-by.auth-made,.made-by.share-made{
  position:relative;z-index:1;border:0;justify-content:center;padding:18px 16px 22px;
}
.made-by.auth-made{position:fixed;left:0;right:0;bottom:0;padding-bottom:16px}
.made-by.auth-made .made-by-txt,.made-by.share-made .made-by-txt{display:flex;align-items:baseline;gap:8px}
.made-by.auth-made .made-by-txt span,.made-by.share-made .made-by-txt span{display:inline}

/* 제품 마크는 정사각이다 — min2joy 심볼용 크기 규칙을 덮는다 */
.auth-head .mark .prod-mark svg{width:44px;height:44px}
.auth-head .mark .prod-mark svg{border-radius:22%;box-shadow:var(--shadow)}
.auth-head .mark strong{font-size:18px}
.auth-head .mark small{font-family:var(--sans);font-size:11.5px;letter-spacing:0;text-transform:none;margin-top:2px;line-height:1.4}
.auth-head h1[hidden],.auth-head p[hidden]{display:none}
.auth-head p{margin-top:0}

/* 글이 한 단어만 남고 줄바꿈되지 않도록 — 짧은 안내문은 균형 있게 끊는다 */
.auth-head p,.auth-head .mark small,.help,.empty p,.alert,.made-by-txt span{text-wrap:pretty}
.auth-head p,.empty p,.empty h3{text-wrap:balance}
.made-by.short .made-by-txt span{font-size:10.5px}

/* ─── 짧은 글의 줄 배분 ───────────────────────────────
   설명·메타처럼 작은 글씨는 마지막 줄에 한 조각만 남으면 지저분하다.
   balance 는 줄 길이를 고르게 맞춰 그 조각을 없앤다. */
.eyebrow,.desc,.help,.hint,.empty p,.card > p,.note,.muted-note,
.set-note,.share-note,.side-note,.field .help,.page-h p,.sec-h p{text-wrap:balance}
.card .desc,.proj-card .desc{text-wrap:balance;overflow-wrap:break-word}
/* 메타 한 줄(코드 · 날짜)은 가운데서 끊기지 않게 조각을 묶는다 */
.eyebrow{word-break:keep-all}

/* ═══ 진행 표시: 회사 심볼이 그대로 돈다 ═══════════════
   눈이 번갈아 뛰고 입이 그려졌다 지워진다. 멈추면 끝난 것이다. */
.ci-spin svg{overflow:visible}
.ci-spin .s-eye{transform-origin:center;transform-box:fill-box}
.ci-spin .s-l{animation:ciHop 1.05s var(--ease) infinite}
.ci-spin .s-r{animation:ciHop 1.05s var(--ease) infinite .34s}
.ci-spin .s-smile{
  color:var(--pine);
  stroke-dasharray:96;stroke-dashoffset:0;
  animation:ciDraw 1.4s var(--ease) infinite;
}
@keyframes ciHop{
  0%,62%,100%{transform:translateY(0) scale(1)}
  28%{transform:translateY(-22%) scale(1.06)}
}
@keyframes ciDraw{
  0%{stroke-dashoffset:96}
  42%{stroke-dashoffset:0}
  76%{stroke-dashoffset:0}
  100%{stroke-dashoffset:-96}
}
@media (prefers-reduced-motion:reduce){
  .ci-spin .s-eye,.ci-spin .s-smile{animation:none}
  .ci-spin .s-smile{stroke-dashoffset:0}
}

/* 글자 옆에 붙는 진행 표시 */
.live-label{display:inline-flex;align-items:center;gap:6px}
.chip .ci-spin{margin-right:-1px}
.chip.running{display:inline-flex;align-items:center;gap:6px}

/* 처음 화면을 여는 동안 */
.boot-spin svg{overflow:visible}

/* 화면을 여는 동안 — 아래쪽에 조용히 뜬다 */
.page-loading{
  position:fixed;left:50%;bottom:22px;transform:translateX(-50%);z-index:80;
  display:flex;align-items:center;gap:9px;
  padding:8px 14px 8px 11px;border-radius:var(--r-pill);
  background:var(--surface);border:1px solid var(--line);box-shadow:var(--shadow-lg);
  font-size:12.5px;color:var(--mute);
  animation:rise .18s var(--ease) both;
}

/* 진행 표시가 들어간 자리 정돈 */
.stack-h h2{display:inline-flex;align-items:center;gap:7px}
/* 심볼이 이미 살아 있음을 말하므로 정적인 점은 뺀다 */
.chip.running::before{display:none}
.chip.running .ci-spin{margin-left:-2px}

/* ─── 모바일에서 화면이 튀지 않게 ─────────────────────────
   iOS 는 viewport 의 user-scalable=no 를 무시한다. 대신 글자가 16px 보다 작은
   입력칸에 포커스가 가면 제멋대로 확대해 버린다. 좁은 화면에서만 16px 로 올려
   그 확대를 막는다. (확대 자체를 막는 것은 viewport 쪽이 맡는다) */
@media (max-width: 640px) {
  .inp, textarea.inp, select.inp, input, textarea, select,
  .topbar .search input { font-size: 16px; }
  .inp.mono { font-size: 16px; }
}

/* 알림 버튼은 팝업의 기준점이다.
   넓은 화면에서는 검색이 남는 자리를 밀어내 오른쪽에 붙으므로 여기에 auto 를 주지 않는다.
   둘 다 auto 를 가지면 남는 폭을 반씩 나눠 가져 검색창이 한가운데에 붕 뜬다. */
.bell-wrap{position:relative}

/* ─── 좁은 화면의 상단바 ───────────────────────────────
   폭이 모자라면 검색칸이 아래 줄로 내려간다. 그때 알림 버튼이 줄 가운데
   어정쩡하게 남으면, 오른쪽에 붙어 열리는 드롭다운이 화면 밖으로 잘려 나간다.
   검색을 아래 줄로 명시적으로 내리고 알림은 첫 줄 오른쪽 끝에 고정한다. */
@media (max-width: 640px) {
  .topbar{gap:8px;padding:10px 12px}
  .topbar .back{order:0}
  .topbar .crumb{order:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .bell-wrap{order:2;margin-left:auto}

  /* 좁은 화면에서는 뒤로 가기 버튼만 둔다.
     지금 어디인지는 화면 안의 제목이 말해주고, 프로젝트는 왼쪽 메뉴에 늘 떠 있다.
     글자까지 두면 자리를 먹어 알림 종이 둘째 줄로 밀리고, 그러면 드롭다운이 잘린다. */
  .topbar .crumb{display:none}
  .topbar .search{order:3;flex-basis:100%;margin-left:0;min-width:0}

  /* 드롭다운은 화면 안에 들어오게 폭을 맞춘다 */
  .notif-pop{width:min(340px, calc(100vw - 24px));right:0;max-height:70vh}
  .projmenu{max-width:calc(100vw - 24px)}
}

/* 이름이 짧아졌으니(AI.Go) 조금 키워 마크와 균형을 맞춘다 */
.brand-txt strong{font-size:16px;letter-spacing:-.02em}
.auth-head .mark strong{font-size:22px;letter-spacing:-.02em}

/* ─── 순서가 있는 안내 ─────────────────────────────────
   세션을 붙이는 일은 순서를 틀리면 안 된다(저장소에 들어간 뒤 붙여야 한다).
   번호를 눈에 보이게 해서 순서 자체가 안내가 되게 한다. */
.step{display:flex;gap:12px;padding:14px 0;border-top:1px solid var(--line-soft)}
.step:first-of-type{border-top:0;padding-top:0}
.step-n{
  flex:0 0 22px;height:22px;border-radius:50%;background:var(--pine);color:var(--paper);
  display:grid;place-items:center;font-family:var(--mono);font-size:11px;font-weight:700;margin-top:1px;
}
.step-b{min-width:0;flex:1}
.step-t{font-size:13.5px;font-weight:600;margin-bottom:7px;letter-spacing:-.01em}
.step .logbox{margin:0}

/* 도구 설명 목록 — 이름은 코드, 설명은 글 */
.kv.tools{grid-template-columns:130px 1fr;gap:6px 12px;align-items:start}
/* 도구 이름은 대소문자가 그대로여야 한다 — 실제로 부를 때 쓰는 이름이다 */
.kv.tools dt{font-family:var(--mono);font-size:11.5px;color:var(--ink);text-transform:none;letter-spacing:0}
.kv.tools dd{font-size:12px;line-height:1.55;margin:0}
.warn-note{border-left:2px solid var(--mark);padding-left:9px}

@media (max-width:640px){
  .kv.tools{grid-template-columns:1fr;gap:2px 0}
  .kv.tools dd{margin-bottom:8px}
}

/* ─── 좁은 화면: 검색을 아이콘으로 접는다 ─────────────
   검색창이 한 줄을 통째로 쓰면 상단바가 100px 을 넘어 화면의 15% 를 고정으로
   가져간다. 평소에는 아이콘만 두고, 누를 때만 아래로 펼친다. */
.search-toggle{display:none}
@media (max-width: 640px) {
  .topbar{padding:8px 12px;gap:8px}
  .search-toggle{display:inline-flex;order:2;margin-left:auto}
  .bell-wrap{order:3;margin-left:0}
  .topbar .search{display:none}
  .topbar.search-on .search{display:flex;order:4;flex-basis:100%;margin:0;min-width:0}
  .topbar.search-on .search-toggle{background:var(--surface-2);border-color:var(--ink)}
}

/* ─── 완료 리포트 요약 ─────────────────────────────────
   요구사항 상세의 주인공은 요구사항이다. 보고서는 짧게 걸쳐두고
   자세한 것은 모달로 넘긴다. */
/* 세 줄에서 자르던 것을 없앴다. 에이전트가 "무엇이 아직 안 되는지" 적어 둔 대목이
   늘 잘려 나갔고, 그걸 읽으려면 보고서를 따로 열어야 했다. */
.report-brief{font-size:13.5px;line-height:1.7;margin:0;color:var(--ink)}
.report-brief > :first-child{margin-top:0}
.report-brief > :last-child{margin-bottom:0}

/* 보고서 원문 모달 — 화면을 옮기지 않고 그 자리에서 본다 */
.report-modal-body{padding:0;background:var(--paper)}
.report-frame.modal-report{
  width:100%;height:min(72vh, 760px);border:0;display:block;background:var(--surface);
}

/* ─── 요구사항 체크 ────────────────────────────────────
   "무엇을 요구했고 그래서 어떻게 됐는가"를 한 줄씩 나란히 놓는다. */
.ac-check{display:flex;flex-direction:column;gap:2px}
.ac-top{margin-bottom:14px}
.ac-bar{display:flex;height:10px;border-radius:var(--r-pill);overflow:hidden;background:var(--line-soft)}
.ac-bar .seg{display:block;height:100%}
.ac-bar .seg.met{background:var(--leaf)}
.ac-bar .seg.partial{background:var(--warn)}
.ac-bar .seg.unmet{background:var(--mark)}
.ac-bar .seg.pending{background:var(--line)}
.ac-legend{display:flex;gap:14px;flex-wrap:wrap;margin-top:8px;font-size:11.5px;color:var(--mute)}
.ac-legend .lg{display:inline-flex;align-items:center;gap:5px}
.ac-legend i{width:8px;height:8px;border-radius:2px;display:block}
.ac-legend .met i{background:var(--leaf)}
.ac-legend .partial i{background:var(--warn)}
.ac-legend .unmet i{background:var(--mark)}
.ac-legend .pending i{background:var(--line)}

.ac-row{display:flex;gap:11px;padding:13px 0;border-top:1px solid var(--line-soft)}
.ac-row:first-of-type{border-top:0}
.ac-n{
  flex:0 0 22px;height:22px;border-radius:50%;display:grid;place-items:center;
  font-family:var(--mono);font-size:11px;background:var(--surface-2);color:var(--mute);margin-top:1px;
}
.ac-row.met .ac-n{background:var(--ok-soft);color:var(--leaf)}
.ac-row.partial .ac-n{background:var(--warn-soft);color:#6b5216}
.ac-row.unmet .ac-n{background:var(--mark-soft);color:var(--mark)}
.ac-body{min-width:0;flex:1}
.ac-ask{display:flex;gap:8px;align-items:baseline;margin-bottom:6px}
.ac-ask .eyebrow{flex:0 0 auto}
.ac-ask > span:last-child{font-size:13.5px;font-weight:600;line-height:1.5}
.ac-got{display:flex;gap:8px;align-items:baseline}
.ac-got .tag{
  flex:0 0 auto;font-family:var(--mono);font-size:10.5px;padding:2px 8px;border-radius:var(--r-pill);
}
.ac-got .tag.met{background:var(--ok-soft);color:var(--leaf)}
.ac-got .tag.partial{background:var(--warn-soft);color:#6b5216}
.ac-got .tag.unmet{background:var(--mark-soft);color:var(--mark)}
.ac-got .tag.pending{background:var(--surface-2);color:var(--mute)}
.ac-note{font-size:12.5px;color:var(--mute);line-height:1.6}

@media (max-width:640px){
  .ac-ask{flex-direction:column;gap:2px}
  .ac-got{flex-direction:column;gap:4px}
  .report-frame.modal-report{height:min(64vh, 560px)}
}

/* 요구사항 체크 — 두 축을 나눠 보여준다 */
.sec-h{display:flex;align-items:baseline;gap:8px;margin:0 0 10px;padding-bottom:7px;border-bottom:1px solid var(--line)}
.sec-h h4{margin:0;font-size:13px;letter-spacing:-.01em}
.resp-block{margin-bottom:22px}
.resp-row{display:flex;gap:11px;padding:12px 0;border-top:1px solid var(--line-soft)}
.resp-row:first-of-type{border-top:0}
.resp-row.done .ac-n{background:var(--ok-soft);color:var(--leaf)}
.resp-row.partial .ac-n{background:var(--warn-soft);color:#6b5216}
.resp-row.skipped .ac-n{background:var(--mark-soft);color:var(--mark)}
.ac-how{display:flex;gap:8px;align-items:baseline;margin-bottom:6px}
.ac-how .eyebrow{flex:0 0 auto}
.ac-how > span:last-child{font-size:12.5px;line-height:1.6;color:var(--ink)}
@media (max-width:640px){ .ac-how{flex-direction:column;gap:2px} }

/* ─── @멘션 자동완성 ───────────────────────────────────
   이름을 외워 정확히 치게 두면 오타 하나로 아무도 부르지 못한다. */
.mention-pop{
  position:absolute;left:0;right:0;top:calc(100% + 4px);z-index:60;
  background:var(--surface);border:1px solid var(--ink);border-radius:var(--r);
  box-shadow:0 8px 24px rgba(20,20,22,.16);overflow:hidden;max-height:220px;overflow-y:auto;
}
.mention-pop.hidden{display:none}
.mention-item{
  display:flex;align-items:baseline;gap:8px;width:100%;border:0;background:transparent;
  padding:8px 11px;text-align:left;font-size:13px;border-bottom:1px solid var(--line-soft);
}
.mention-item:last-child{border-bottom:0}
.mention-item:hover,.mention-item.on{background:var(--surface-2)}
.mention-item .nm{font-weight:600}
.mention-item .un{font-family:var(--mono);font-size:11px;color:var(--mute)}

/* ── 아래로 당겨 새로고침 ─────────────────────────────
   화면 위쪽 가운데에 붙어 있다가, 당기는 만큼 따라 내려온다. */
.ptr{
  position:fixed;top:-46px;left:50%;transform:translate(-50%,0);
  width:34px;height:34px;border-radius:50%;
  background:var(--surface);border:1px solid var(--line);
  box-shadow:0 3px 12px rgba(20,20,22,.12);
  display:grid;place-items:center;z-index:80;
  opacity:0;pointer-events:none;transition:opacity .15s ease;
}
.ptr.on{opacity:1}
.ptr-spin{
  width:15px;height:15px;border-radius:50%;
  border:2px solid var(--line);border-top-color:var(--mute);
  transition:border-top-color .15s ease;
}
.ptr.ready .ptr-spin{border-top-color:var(--leaf)}
.ptr.spin{transition:transform .2s ease}
.ptr.spin .ptr-spin{animation:ptr-turn .7s linear infinite;border-top-color:var(--leaf)}
@keyframes ptr-turn{to{transform:rotate(360deg)}}

/* ── 알림 설정 ────────────────────────────────────── */
.kinds{display:grid;gap:2px}
.kind-row{
  display:flex;align-items:flex-start;gap:9px;padding:10px 2px;
  border-bottom:1px solid var(--line-soft);flex-wrap:wrap;
}
.kind-row:last-child{border-bottom:0}
.kind-row input{margin-top:2px}
.kind-help{
  flex:1 0 100%;padding-left:25px;margin-top:-2px;
  font-size:11.5px;color:var(--mute);word-break:keep-all;
}

/* ── 새 버전 알림 ─────────────────────────────────────
   쓰던 것이 있어 바로 새로고침하지 못할 때만 보인다. */
.newver{
  position:fixed;left:50%;bottom:18px;transform:translate(-50%, 24px);
  display:flex;align-items:center;gap:12px;z-index:90;
  padding:10px 12px 10px 16px;border-radius:999px;
  background:var(--pine);color:#fff;font-size:12.5px;
  box-shadow:0 8px 26px rgba(20,20,22,.28);
  opacity:0;transition:opacity .2s ease, transform .24s cubic-bezier(.2,.8,.3,1);
  max-width:calc(100vw - 28px);word-break:keep-all;
}
.newver.on{opacity:1;transform:translate(-50%, 0)}
.newver .btn{flex:0 0 auto}

/* ── 본문 + 옆칸 ──────────────────────────────────────
   인라인 style 로 열 너비를 박아두면 좁은 화면에서도 그대로 남는다 —
   인라인이 스타일시트를 이긴다. 실제로 개발 지침 화면에서 편집기가
   90px 폭으로 눌려 글자가 한 자씩 줄바꿈됐다. 그래서 클래스로 둔다. */
.grid-2.with-side{grid-template-columns:1fr 300px}
@container (max-width: 860px){
  .grid-2.with-side{grid-template-columns:1fr}
  /* 탭이 화면보다 넓으면 그 안에서만 옆으로 움직인다 (본문은 밀리지 않는다) */
  .tabs{margin-left:-2px;padding-left:2px;scrollbar-width:none}
  .tabs::-webkit-scrollbar{display:none}
  .tabs button{flex:0 0 auto}
}

/* ── 좁은 화면의 단계 표시 ─────────────────────────────
   5칸에 "STEP n · 이름 · 시각"을 다 넣으면 590px 가 되어 옆으로 밀린다.
   지금 어디까지 왔는지만 알면 되는 자리다 — 이름만 남기고 한 줄에 담는다.
   시각은 위쪽 머리글(작성·제출)과 실행 현황 카드에 이미 있다. */
@container (max-width: 560px){
  .flow{overflow-x:visible}
  .flow li{min-width:0;flex:1 1 0;padding:7px 4px;text-align:center}
  .flow li .s,.flow li .d{display:none}
  .flow li .t{font-size:11.5px;font-weight:600;margin:0;white-space:nowrap}
  .flow li.done .t::after{content:"";}          /* 체크는 자리만 먹는다 */
  .flow li.done{background:var(--ok-soft)}
  .flow li.done .t{color:var(--leaf)}
  .flow li.now{border-radius:0}
  .flow li.now .t{color:#fff}
}

/* 좁은 화면에서는 감춘다 — 휴대폰에는 그 키가 없고, 남으면 한 조각만 끊겨 내려간다 */
@container (max-width: 560px){
  .only-wide{display:none}
  .hint-comment{word-break:keep-all}
}

/* ── 완료 도장 ────────────────────────────────────────
   종이에 찍은 것처럼 비스듬히. 색은 잎사귀 녹색을 옅게 쓴다 —
   진하게 하면 제목보다 먼저 눈에 들어와 읽는 순서가 뒤집힌다. */
.stamp-wrap{
  flex:0 0 auto;color:var(--leaf);opacity:.5;
  transform:rotate(-11deg);
  display:grid;place-items:center;pointer-events:none;
  align-self:center;
}
.stamp{display:block}
@container (max-width: 560px){
  /* 좁은 화면에서는 작게. 버튼들과 자리를 다투면 안 된다 */
  .stamp-wrap{position:absolute;right:2px;top:-4px;opacity:.34}
  .stamp-wrap .stamp{width:58px;height:58px}
  .page-h{position:relative}
}

/* 목록의 완료 도장 — 배지 자리에 들어간다.
   음수 여백으로 행 높이를 배지와 같게 맞춘다. 완료 행만 불쑥 높으면 목록이 들쭉날쭉해진다. */
.row-stamp{
  flex:0 0 auto;color:var(--leaf);opacity:.62;
  transform:rotate(-9deg);display:grid;place-items:center;
  width:auto;height:30px;margin:-4px 0;
}
.row-stamp svg{display:block}

/* ── 뒤로 가기 ────────────────────────────────────────
   빵부스러기는 글자일 뿐이라 상세로 들어가면 돌아갈 길이 없었다.
   최상위 화면에서는 감춘다 — 갈 곳이 없는 버튼은 눌러보게 만들고 실망시킨다. */
.topbar .back{flex:0 0 auto;padding:0;width:32px;height:32px}
.topbar .back.hidden{display:none}

/* ─── 기억 상자 ─────────────────────────────────────────── */
/* 카드 하나가 한 가지 사실이다. 제목만 훑고 필요한 것만 펴 읽을 수 있어야 한다. */
.card.mem{padding:14px 16px;margin-bottom:10px}
.card.mem.pinned{border-color:var(--ink)}
.mem-h{display:flex;gap:10px;align-items:flex-start}
.mem-h .acts{flex:0 0 auto;display:flex;gap:6px}
.mem-t{margin:0 0 3px;font-size:14px;line-height:1.45;display:flex;gap:6px;align-items:baseline;flex-wrap:wrap}
.mem-t .pin{font-size:12px}
.mem-t .tag{font:11px/1 var(--mono);padding:3px 7px;border:1px solid var(--line);border-radius:999px;color:var(--muted)}
.mem-b{margin-top:9px;font-size:13px;line-height:1.7;word-break:keep-all;overflow-wrap:anywhere}
.mem-b :first-child{margin-top:0}
.mem-b :last-child{margin-bottom:0}
.mem-b pre,.mem-b table{overflow-x:auto;max-width:100%}
@media (max-width:640px){
  /* 좁은 화면에서는 버튼이 제목을 밀어낸다. 아래로 내린다. */
  .mem-h{flex-direction:column;gap:8px}
  .mem-h .acts{width:100%}
  .mem-h .acts .btn{flex:1}
}
.card.mem.file .mem-t a{color:inherit;text-decoration:none;border-bottom:1px solid var(--line)}
.card.mem.file .mem-t a:hover{border-color:var(--ink)}
.fthumb{flex:0 0 auto;width:64px;height:64px;border:1px solid var(--line);border-radius:8px;overflow:hidden;display:block}
.fthumb img{width:100%;height:100%;object-fit:cover;display:block}
.fnote{font-size:12.5px;line-height:1.6;margin:2px 0 3px;word-break:keep-all}
/* 링크로 만든 버튼에 밑줄이 남으면 버튼으로 안 보인다 */
a.btn{text-decoration:none}
/* 링크로 만든 버튼은 글자가 왼쪽에 붙는다 — 옆의 진짜 버튼과 나란히 두면 어긋나 보인다 */
a.btn{justify-content:center;text-align:center}
/* 지우기는 조심스러운 자리다. 나머지 둘과 같은 폭으로 늘리지 않는다. */
.mem-h .acts .btn.ghost{flex:0 0 auto}

/* ─── 안 접히는 한 줄 ────────────────────────────────────── */
/* 사람과 에이전트가 쓴 글에는 접을 자리가 없는 한 줄이 섞여 들어온다 —
   긴 URL, 경로, 명령줄. 그 한 줄이 화면 전체를 옆으로 밀면 왼쪽 글자가 잘려 나간다.
   (실제로 판정 근거의 URL 하나 때문에 상세 화면이 203px 옆으로 밀렸다.)
   잘라서라도 접되, 한글은 단어 단위로 끊는다.
   코드·표는 접을 수 없으니 제 상자 안에서만 밀리게 둔다. */
.main *:not(pre):not(code):not(table):not(svg):not(svg *){word-break:keep-all;overflow-wrap:anywhere}
.main pre,.main table{overflow-x:auto;max-width:100%}

/* 좁은 화면에서 9줄짜리 입력칸은 상자를 다 잡아먹는다.
   아래에 뭐가 더 있는지 보이지 않으면 사람은 없는 줄 안다. */
@media (max-width:640px){
  .modal-b textarea{min-height:110px;max-height:32vh}
}

/* ─── 연결된 프로젝트 ───────────────────────────────────── */
.link-row{display:flex;gap:12px;align-items:flex-start;padding:12px 0;border-top:1px solid var(--line-soft)}
.link-row:first-of-type{border-top:0}
.link-row.warn{background:var(--warn-soft);margin:0 -12px;padding:12px;border-radius:var(--r)}
.link-row .acts{flex:0 0 auto;display:flex;gap:6px}
.link-t{display:flex;gap:8px;align-items:baseline;flex-wrap:wrap;margin-bottom:3px}
.link-t a{font-weight:600;font-size:13.5px;color:inherit;text-decoration:none;border-bottom:1px solid var(--line)}
.link-t a:hover{border-color:var(--ink)}
.warn-line{margin-top:6px;color:#6b5216;line-height:1.6}
.empty.sm{padding:14px;text-align:left}
/* 좁은 빈 상태는 왼쪽 정렬인데, .empty > span 의 가운데 정렬이 남아
   제목은 왼쪽 · 설명은 가운데로 어긋나 보였다. */
.empty.sm > span{margin:0;max-width:none}
.empty.sm b{display:block;font-size:13px;margin-bottom:3px}
@media (max-width:640px){
  /* 좁은 화면에서는 버튼이 이름을 밀어낸다. 아래로 내린다. */
  .link-row{flex-direction:column;gap:8px}
  .link-row .acts{width:100%}
  .link-row .acts .btn{flex:1}
}
/* 접어 둔 칸이 펴질 때 위 체크박스와 붙어 보이지 않게 */
#pj-link-fields{margin-top:10px;padding-left:22px;border-left:2px solid var(--line-soft)}
/* 알림을 누르고 들어왔을 때 "이거였다"를 잠깐 짚어준다.
   화면까지만 데려다 놓으면 사람은 긴 글에서 새 글을 다시 찾아야 한다. */
.cmt.just-came{animation:came 3.2s ease}
@keyframes came{
  0%,55%{background:var(--ok-soft);box-shadow:0 0 0 6px var(--ok-soft);border-radius:var(--r)}
  100%{background:transparent;box-shadow:none}
}
@media (prefers-reduced-motion:reduce){ .cmt.just-came{animation:none;outline:2px solid var(--leaf);outline-offset:4px} }
/* 프로젝트 카드의 칩 두 개 — 좁아지면 아래로 접힌다 */
.proj-card .chiprow{display:flex;gap:6px;flex-wrap:wrap;align-items:center;align-self:flex-start}

/* ─── 이미지 보기 ───────────────────────────────────────── */
.zoom-wrap{display:flex;flex-direction:column;gap:10px}
.zoom-bar{display:flex;gap:6px;align-items:center}
.zoom-bar .btn{min-width:34px}
.zoom-lv{font:12px var(--mono);color:var(--mute);min-width:52px;text-align:center}
/* touch-action:none 이 있어야 손가락 동작을 브라우저가 가로채지 않는다 */
.zoom-stage{position:relative;overflow:hidden;touch-action:none;user-select:none;
  background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r);
  height:min(62vh,560px);display:grid;place-items:center}
.zoom-stage img{max-width:100%;max-height:100%;display:block;
  transform-origin:center center;will-change:transform}
.zoom-stage.zoomed{cursor:grab}
.zoom-stage.zoomed:active{cursor:grabbing}
@media (prefers-reduced-motion:no-preference){
  .zoom-stage img{transition:transform .08s linear}
}

/* ─── 이어져 온 사슬 ────────────────────────────────────── */
/* 상자 모양만 정한다. 줄을 어떻게 세울지는 안쪽이 정한다 —
   여기서 세로로 못박아 두는 바람에 한 줄짜리 띠가 세 줄로 쌓였다. */
.chain{padding:10px 12px;border:1px solid var(--line);border-radius:var(--r);background:var(--surface-2)}
.chain.linked{display:flex;gap:10px;align-items:baseline;flex-wrap:wrap}
/* 한 줄로 끝낸다. 사슬을 통째로 늘어놓으면 좁은 화면에서 접혀 어지럽다. */
.ch-one{display:flex;gap:8px;align-items:center;min-width:0;color:inherit;text-decoration:none}
.ch-one .eyebrow{flex:0 0 auto}
.ch-one:hover .ch-item{border-color:var(--ink)}
.ch-key{font:12px var(--mono)}
/* 제목은 남는 만큼만 차지하고 넘치면 자른다 — 번호와 상태가 밀려나면 안 된다 */
.ch-t{flex:1 1 auto;min-width:0;font-size:12.5px;color:var(--mute)}
.ch-line{display:flex;gap:6px;align-items:center;flex-wrap:wrap;min-width:0}
.ch-item{display:inline-flex;gap:6px;align-items:center;flex:0 0 auto;
  color:inherit;text-decoration:none;padding:3px 8px;border:1px solid var(--line);border-radius:999px;background:var(--surface)}
.ch-item:hover{border-color:var(--ink)}
.ch-now{font:12px var(--mono);padding:2px 8px;border-radius:999px;background:var(--ink);color:#fff}
.ch-arrow{color:var(--mute);font-size:12px}
.lk-item{display:inline-flex;gap:6px;align-items:center;color:inherit;text-decoration:none;
  padding:3px 9px;border:1px solid var(--line);border-radius:999px;background:var(--surface);font-size:12.5px}
.lk-item:hover{border-color:var(--ink)}
.lk-item.off{opacity:.55;cursor:default}
.lk-name{display:inline-flex;gap:6px;align-items:baseline;flex-wrap:wrap}

/* ─── 프로젝트 고르기 ───────────────────────────────────── */
.projmenu .more{border-top:1px solid var(--line-soft);color:var(--mute);font-size:12.5px}
.projmenu .foot{border-top:1px solid var(--line);font-weight:600}
.pick{display:flex;flex-direction:column;gap:10px}
.pick-list{max-height:min(50vh,420px);overflow-y:auto;overscroll-behavior:contain;
  border:1px solid var(--line);border-radius:var(--r)}
.pick-list button{display:flex;flex-direction:column;gap:2px;align-items:flex-start;width:100%;
  padding:9px 12px;border:0;border-bottom:1px solid var(--line-soft);background:transparent;
  text-align:left;font:inherit;font-size:13px;cursor:pointer}
.pick-list button:last-child{border-bottom:0}
.pick-list button:hover{background:var(--surface-2)}
.pick-list button.on{background:var(--ok-soft)}
.pick-list small{color:var(--mute);font:11.5px var(--mono)}

/* ─── 보고서 본문 ───────────────────────────────────────── */
/* 처음에 stack-b 라는 이름을 붙였는데 진행 단계 카드가 이미 쓰던 이름이었다.
   테두리만 따라붙고 여백은 없어서, 글자가 상자에 딱 붙어 보였다.
   이름이 겹치면 내가 안 쓴 규칙이 따라온다. */
.report-body{font-size:13px;line-height:1.75}
.report-body > :first-child{margin-top:0}
.report-body > :last-child{margin-bottom:0}
.report-body .eyebrow{display:block;margin-bottom:6px}
.report-body .md + .eyebrow,
.report-body .ac + .eyebrow,
.report-body > div + .eyebrow{margin-top:18px}
.report-body .ac{margin:0 0 14px;padding-left:0;list-style:none}
.report-body .ac li{display:flex;gap:9px;align-items:flex-start;padding:6px 0}

/* 에이전트가 그 댓글에 답을 쓰는 중 — 물어놓고 "읽기는 한 건가" 를 몰라 기다리지 않게 */
.cmt .answering{display:inline-flex;align-items:center;gap:6px;font-size:11.5px;color:var(--mute)}
.cmt .answering .spin{width:11px;height:11px;border-width:2px}

/* 첨부 미리보기 — 앱 안에서 연다. 새 탭은 빈 화면이 되기 쉽다(브라우저가 내려받기로 넘긴다) */
.file-frame{width:100%;height:min(62vh,680px);border:1px solid var(--line);border-radius:var(--r);background:var(--surface-2)}
.file-row .as-link{background:none;border:0;padding:0;text-align:left;font:inherit;color:var(--link,#2f6fd0);cursor:pointer}
.file-row .as-link:hover{text-decoration:underline}
/* PDF 를 직접 그린다 — 페이지를 세로로 쌓고 화면 폭에 맞춘다 */
/* ─── 첨부 뷰어 ───────────────────────────────────────
   PDF 말고도 글·표·동영상을 같은 자리에서 본다. 못 여는 형식은
   빈 칸을 남기지 않고 내려받기로 데려간다. */

/* 글로 된 파일 — 마크다운·소스·로그 */
.text-stage{max-height:min(66vh,700px);overflow:auto;background:var(--surface-2);
  border:1px solid var(--line);border-radius:var(--r);padding:14px 16px}
.text-body{margin:0;font-family:var(--mono);font-size:12px;line-height:1.7;
  white-space:pre;overflow-x:auto;color:var(--ink)}

/* 마크다운. 본문 글꼴로 읽되 화면 안에서만 넓어지게 둔다. */
.md-body{font-size:13.5px;line-height:1.75;color:var(--ink)}
.md-body > *:first-child{margin-top:0}
.md-body > *:last-child{margin-bottom:0}
.md-body .md-h{margin:20px 0 8px;line-height:1.35;font-weight:650}
.md-body h1.md-h{font-size:19px;padding-bottom:6px;border-bottom:1px solid var(--line)}
.md-body h2.md-h{font-size:16.5px;padding-bottom:5px;border-bottom:1px solid var(--line)}
.md-body h3.md-h{font-size:15px}
.md-body h4.md-h,.md-body h5.md-h,.md-body h6.md-h{font-size:13.5px;color:var(--mute)}
.md-body .md-p{margin:0 0 11px}
.md-body .md-list{margin:0 0 11px;padding-left:22px}
.md-body .md-list .md-list{margin:5px 0 0}
.md-body li{margin:3px 0}
.md-body .md-hr{border:0;border-top:1px solid var(--line);margin:18px 0}
.md-body .md-quote{margin:0 0 11px;padding:2px 0 2px 13px;border-left:3px solid var(--line);color:var(--mute)}
.md-body code{font-family:var(--mono);font-size:.88em;background:var(--surface-2);
  border:1px solid var(--line);border-radius:5px;padding:1px 5px}
.md-body .md-code{margin:0 0 12px;background:#1b1c1f;border-radius:var(--r);
  padding:12px 14px;overflow-x:auto}
.md-body .md-code code{background:transparent;border:0;padding:0;color:#d7d7d2;
  font-size:12px;line-height:1.65;white-space:pre}
.md-body .md-img{max-width:100%;height:auto;border-radius:var(--r);margin:4px 0}
.md-body a{color:var(--link,#2f6fd0);text-decoration:underline;text-underline-offset:2px}

/* 표 — 마크다운 표와 csv 가 같은 모양을 쓴다 */
.md-table-wrap{overflow-x:auto;margin:0 0 12px;border:1px solid var(--line);border-radius:var(--r)}
.md-table{border-collapse:collapse;width:100%;font-size:12.5px;background:var(--surface)}
.md-table th,.md-table td{border-bottom:1px solid var(--line);padding:7px 11px;
  text-align:left;vertical-align:top;white-space:pre-wrap;word-break:keep-all}
.md-table thead th{background:var(--surface-2);font-weight:600;position:sticky;top:0}
.md-table tbody tr:last-child td{border-bottom:0}

/* 동영상·소리 */
.media-stage{background:#101012;border-radius:var(--r);display:grid;place-items:center;padding:10px}
.media-stage video{max-width:100%;max-height:min(62vh,660px);display:block;border-radius:var(--r)}
.media-stage.audio{background:var(--surface-2);border:1px solid var(--line);padding:22px}
.media-stage audio{width:100%}

/* 못 여는 형식 — 여기서 바로 받게 한다 */
.nopreview{display:grid;justify-items:center;gap:7px;text-align:center;
  padding:34px 18px;background:var(--surface-2);border:1px dashed var(--line);border-radius:var(--r)}
.nopreview-ext{font-family:var(--mono);font-size:12px;font-weight:650;letter-spacing:.04em;
  color:var(--mute);background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r);padding:9px 13px}
.nopreview b{font-size:13.5px}
.nopreview-name{font-size:12.5px;color:var(--mute);word-break:break-all;max-width:34em}
.nopreview .btn{margin-top:6px}

.pdf-stage{max-height:min(66vh,700px);overflow:auto;background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r);padding:8px}
.pdf-stage .pdf-page{display:block;margin:0 auto 8px;background:#fff;box-shadow:var(--shadow-sm)}

/* ─── 사용 방법 ────────────────────────────────────
   안내서를 앱 안에 그대로 띄운다. 안내서가 화면 폭에 맞춰 알아서 접히므로
   여기서 할 일은 **남은 높이를 전부 넘겨주는 것**뿐이다. 높이를 숫자로 빼면
   머리말이 한 줄만 늘어도 슬라이드 아래가 잘린다 — 그래서 flex 에 맡긴다. */
.body:has(.manual-wrap){display:flex; flex-direction:column; flex:1; min-height:0; padding-bottom:6px}
.manual-h{display:flex; align-items:baseline; gap:10px; flex-wrap:wrap; margin-bottom:8px}
.manual-h h1{margin:0; font-size:18px; letter-spacing:-.02em}
.manual-h .muted{font-size:12.5px}
.manual-h .acts{margin-left:auto; display:flex; gap:6px}
.manual-wrap{
  border:1px solid var(--line); border-radius:var(--r-lg,10px); overflow:hidden;
  background:var(--surface-2); flex:1; min-height:360px;
}
.manual-frame{display:block; width:100%; height:100%; border:0; background:var(--surface-2)}
