/* layout.css — 헤더·탭·배너, 실행 줄(#runbar), main 의 탭 섹션 프레임, 카드 안 스크롤 */
/* 고정 프레임: 창에 꽉 차고 페이지 스크롤은 없다 — 스크롤은 열·카드 안쪽에서만 (1280×860 프레임 기준).
   body 를 세로 flex 로 잡아 업데이트 바·서버 끊김 배너·헤더·실행 줄이 위에 쌓이고, main 이 남은 높이를 전부 쓴다.
   옛 좌우·상하 드래그 분할(#qwRow/#splitH/#splitV)은 보드가 4열이 되면서 지웠다. */
html,body{height:100%;overflow:hidden}
body{margin:0;background:var(--bg);color:var(--fg);font:var(--fs-body)/1.5 var(--font);display:flex;flex-direction:column}
header{display:flex;align-items:center;gap:4px;padding:10px 16px;border-bottom:1px solid var(--line);background:var(--bg);flex:none;z-index:5}
/* 로고 — 폴리오와 같은 모양(글자 하나). 눈썹 줄은 뺐다: 좁은 화면에서 자리만 먹고,
   두 앱의 머리줄이 서로 다르게 보이는 첫째 까닭이었다. */
.brand{display:flex;align-items:center;line-height:1.1;margin-right:14px}

/* 아이콘 버튼 — 폴리오 `.tb` 와 같은 크기·같은 선 굵기. */
header .tb{width:30px;height:30px;display:grid;place-items:center;padding:0;flex:none;
  border:1px solid var(--line2);border-radius:8px;background:var(--card);color:var(--sub);cursor:pointer}
header .tb:hover{background:var(--hover);color:var(--fg);border-color:var(--line3)}
header .tb svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round}
header .tb[aria-pressed="true"],header .tb.on{background:var(--goldbg);border-color:var(--goldline);color:var(--gold)}
/* 갱신이 도는 중 — 글자를 못 쓰므로(아이콘이다) 아이콘 자체를 돌린다 */
header .tb.busy{color:var(--gold);border-color:var(--goldline)}
header .tb.busy svg{animation:tbspin 1.1s linear infinite}
@keyframes tbspin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion: reduce){header .tb.busy svg{animation:none;opacity:.6}}
/* 점만 남은 연결 표시 */
header .conn .dot{width:9px;height:9px;border-radius:50%;display:block}
/* **화면에서만 숨긴다** — 읽기 프로그램에는 남는다 (연결 상태 글자 등).
   이름이 `.sr` 이었다. 재고 표의 **행 클래스도 `.sr`** 이다(stock row) — 같은 이름,
   다른 뜻이었다. 뒤에 실리는 `tab-stock.css` 가 `display:grid`·`height` 는 덮지만
   `position:absolute`·`width:1px`·`clip-path` 는 안 덮어서, **재고 400줄이 1px 로 잘린 채
   허공에 떠 있었다.** 자리를 안 차지하니 목록만 통째로 사라져 보였다 (대표 화면).
   그래서 이 이름은 **다른 것과 겹칠 수 없는 이름**이어야 한다. */
.a11y-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip-path:inset(50%);white-space:nowrap;border:0}
h1{font-size:var(--fs-h1);margin:0;font-weight:700}
.grow{flex:1}
.ver{color:var(--sub2);font-size:var(--fs-sm)}
#updBar{display:flex;align-items:center;gap:8px;padding:8px 16px;background:var(--goldbg);color:var(--gold2);border-bottom:1px solid var(--line);flex:none}
/* 앱 서버가 죽은 창 (종료된 개발 서버·exe 의 창이 남은 경우) — 「게임 꺼짐」과 구분해 분홍으로 */
#srvBar{display:flex;align-items:center;gap:10px;padding:10px 16px;background:var(--badbg);color:var(--bad);border-bottom:1px solid var(--bad);flex:none;z-index:30;font-size:var(--fs-body)}
#srvBar b{color:var(--bad)}#srvBar button{border-color:var(--bad);color:var(--bad);background:transparent}
#updBar button{border-color:var(--gold);color:var(--gold2)}
/* 실행 줄(▶/■)은 **큐 탭에서만** — 시안 §8 「가공 탭에선 숨김」. 좁은 폭 블록에만 있어 800 설정 탭 위에 실행 줄이
   보였다(실테스트 T3-7). 폭과 무관한 규칙이라 여기에 둔다. main.js markTabs 가 body[data-tab] 을 적는다 */
body[data-tab]:not([data-tab="queue"]) #runbar{display:none}
/* 헤더 탭 (목업: 헤더 안, 골드 밑줄, padding 8/14) */
.tabs{display:flex}
.tabs button{border:none;border-bottom:2px solid transparent;border-radius:0;padding:8px 14px;color:var(--sub);font-size:var(--fs-tab);line-height:1.3}   /* line-height 는 목업 헤더 높이(56px)에 맞춘 값 — body 의 1.5 를 쓰면 4px 높아진다 */
.tabs button:hover{color:var(--fg2)}
.tabs button.on{color:var(--gold2);border-bottom-color:var(--gold);font-weight:600}
/* 탭 옆 숫자 배지 — 목업의 「가공 2」(진행 중인 가공 수). 0 이면 숨긴다 */
.tabs .tcnt{font-family:var(--mono);font-size:var(--fs-sm);color:var(--orange);font-style:normal;margin-left:4px}
#btnSync{margin-left:10px}   /* 목업: 연결 표시와 버튼 사이만 벌린다 */
/* 좁은 창 방어 (QA): 탭이 안 줄어들어 갱신·테마·설정이 화면 밖으로 밀려 누를 수 없었다(700px 이하).
   「데모 연결」도 글자 단위로 세로 배열돼 헤더가 57→93px 로 부풀었다. 버튼은 항상 남기고 탭만 줄인다.
   탭이 5개로 늘어 이 방어가 더 중요해졌다 — .tabs 만 min-width:0 으로 줄어들고 가로 스크롤을 먹는다. */
#connTxt{white-space:nowrap}
header .conn,header .ver,header .badge,header button{flex:none}
.brand{flex:none}
.tabs{min-width:0;overflow-x:auto;scrollbar-width:none}
.tabs::-webkit-scrollbar{display:none}
@media (max-width:1040px){
  header{gap:2px;padding:10px 10px}
  .brand{margin-right:8px}
  .tabs button{padding:8px 9px}
  header .ver{display:none}
  #btnSync{margin-left:6px}
}
@media (max-width:760px){
  #connTxt{display:none}   /* 상태는 점 색·툴팁으로 (connDot 의 title) */
  /* 601~760: 탭 6개 + 단추 4개가 안 들어가 「설정」 탭이 데모 배지 밑에 숨었다(실테스트 2-8). 톱니(#btnSettings)가
     같은 곳으로 가므로 탭 쪽을 숨기고 탭 여백을 줄인다. 600 미만은 mobile.css 가 따로 5등분 탭을 그린다 */
  .tabs button[data-tab="settings"]{display:none}
  .tabs button{padding:8px 7px}
}
/* 목업 RECIPE LIST 의 「정렬」 라벨 — 정렬 세그먼트가 보일 때만 같이 보인다 (list-core 는 #sortSeg 의 hidden 만 토글한다) */
#sortLbl{display:none}
#filterRow:has(#sortSeg:not([hidden])) #sortLbl{display:inline}

/* ── 실행 줄 (#runbar) ──
   ▶시작 ■정지 · 실행 중 배지 · 경과 · 예상 소모 · 오류 시 계속/정지 · 회신 기록. 안쪽은 board.js 가 채운다.
   비어 있는 동안(보드가 아직 안 그려짐)에는 빈 띠가 남지 않게 접는다. */
#runbar{flex:none;background:var(--inset);border-bottom:1px solid var(--line);min-width:0}
#runbar:empty{display:none}

/* ── 본문: 탭 섹션 하나가 남은 높이를 전부 쓴다 ── */
main{flex:1;min-height:0;min-width:0;display:flex;flex-direction:column;overflow:hidden}
main>section{flex:1;min-height:0;min-width:0;display:flex;flex-direction:column}
/* 「아직 불러온 자료가 없습니다」 — 보드 자리를 잡아먹지 않게 한 줄짜리 띠로 (.empty 기본 padding 30px 을 덮는다) */
#emptyCard{flex:none;margin:10px 16px 0;border-radius:8px}
#emptyCard .empty{padding:8px 12px;text-align:left;font-size:var(--fs-sm)}
/* 큐 탭 = 보드(남은 높이 전부) + 보드 발(내용 높이). 보드 안쪽 4열은 board.css 소관 */
#tabQueue{display:grid;grid-template-rows:minmax(0,1fr) auto;min-height:0}
#board{min-height:0;min-width:0;overflow:hidden}
#boardFoot{min-width:0}
#boardFoot:empty{display:none}
/* 가공 대기열 · 재고 · 사전 · 오버레이 탭 — 카드 바깥 여백은 셸이 준다 */
#tabWorks,#tabStock,#tabDict,#tabOverlay{padding:12px 16px}
#tabOverlay{overflow:auto}
.card{background:var(--card);border:1px solid var(--line2);border-radius:12px;overflow:hidden;min-width:0}
/* 카드 안에서만 스크롤: 헤더·발은 고정, 가운데 목록만 흐른다 */
#tabCard,#worksCard{flex:1 1 auto;display:flex;flex-direction:column;min-height:0}
#tabCard>*,#worksCard>*{flex:none}
#tabBody{flex:1 1 auto;min-height:0;overflow:auto}
#works{flex:1 1 auto;min-height:0;overflow:auto}
/* container: 표(재고·사전)가 창이 아니라 「카드 폭」에 반응한다 */
#tabCard{container:tab / inline-size}
/* 가공 대기열이 비거나 접히면 카드가 한 줄 높이만 차지한다 (works.js 가 data-empty·data-collapsed 를 붙인다) */
#worksCard[data-empty],#worksCard[data-collapsed]{flex:none}
