/* ═══ 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:.12em;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}
.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 .t{color:#75766f;margin-right:8px}
.logbox .k{color:#8fb4e8}
.logbox .k.error{color:#e08c72}
.logbox .k.done{color:#8fca9f}

/* ─── 공유 공개 뷰 ────────────────────────────────── */
.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:.08em;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:anywhere 를 준다. */
.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: anywhere }

/* 코드·경로처럼 공백이 없는 문자열은 확실히 끊는다 */
.md code, .md pre, .inp.mono, .diffbox, .logbox,
.kv dd.mono, .code-pill { overflow-wrap: anywhere; word-break: break-word }
.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:anywhere;
}
.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:anywhere}
.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:.1em;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}

/* 로그인·공유 화면에서는 카드 아래 가운데에 놓는다 */
.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:anywhere}
/* 메타 한 줄(코드 · 날짜)은 가운데서 끊기지 않게 조각을 묶는다 */
.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; }
}

/* 알림 버튼은 늘 오른쪽 끝에 붙는다 — 팝업이 이 지점을 기준으로 열린다 */
.bell-wrap{position:relative;margin-left:auto}

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