/* 색은 모두 여기서만 정한다. 기본은 다크, ☰ 메뉴에서 라이트·시스템 설정 따름을 고른다 (data-theme, js/settings/SettingsMenu.js).
   color-scheme: 스크롤바·드롭다운·체크박스 같은 브라우저 기본 부품도 테마 색으로 */
:root{color-scheme:dark;--bg:#1e1f22;--panel:#2b2d31;--head:#303134;--headline:#5c5d61;--cell:#232428;--line:#46484d;--text:#e6e6e6;--dim:#8b9097;--accent:#4c8dff;--accent-text:#8fb5ff;--accent-tint:#4c8dff2e;--bad:#4a2326;--badline:#e5534b;--warnbg:#3d3418;--warntext:#d9a63a;--btn:#383a40;--hover:#43464d;--code:#c9d1d9;--shadow:#0006}
:root[data-theme="light"]{color-scheme:light;--bg:#f5f6f8;--panel:#ffffff;--head:#ececec;--headline:#b4b4b4;--cell:#ffffff;--line:#cdcdcd;--text:#1f2328;--dim:#6b7280;--accent:#2f6fe4;--accent-text:#2f6fe4;--accent-tint:#2f6fe41f;--bad:#fde8e8;--badline:#d93a3a;--warnbg:#fdf3d6;--warntext:#a86b00;--btn:#ffffff;--hover:#eceef1;--code:#24292f;--shadow:#0002}
/* 시스템 설정 따름(data-theme 없음): 윈도우가 라이트면 위의 라이트 값과 같게 */
@media (prefers-color-scheme:light){:root:not([data-theme]){color-scheme:light;--bg:#f5f6f8;--panel:#ffffff;--head:#ececec;--headline:#b4b4b4;--cell:#ffffff;--line:#cdcdcd;--text:#1f2328;--dim:#6b7280;--accent:#2f6fe4;--accent-text:#2f6fe4;--accent-tint:#2f6fe41f;--bad:#fde8e8;--badline:#d93a3a;--warnbg:#fdf3d6;--warntext:#a86b00;--btn:#ffffff;--hover:#eceef1;--code:#24292f;--shadow:#0002}}
*{box-sizing:border-box}
html,body{margin:0;height:100%;background:var(--bg);color:var(--text);font:13px/1.4 system-ui,"Malgun Gothic",sans-serif}
body{display:flex;flex-direction:column}
input,select,button,textarea{font:inherit;color:inherit}
button{background:var(--btn);border:1px solid var(--line);border-radius:4px;padding:4px 10px;cursor:pointer}
button:hover{background:var(--hover)}
button.primary{background:var(--accent);border-color:var(--accent);color:#fff}
button.warn,button.warn:hover{background:var(--badline);border-color:var(--badline);color:#fff}
header{padding:14px 12px;background:var(--panel);border-bottom:1px solid var(--line);text-align:center}
header{position:relative}
header h1{margin:0;font-size:20px}
/* 제목 줄 오른쪽 ☰: 화면 테마 같은 가끔 바꾸는 설정 (아래 .dropmenu 공통 모양보다 우선하도록 header를 붙였다) */
header .appmenu{position:absolute;right:12px;top:50%;transform:translateY(-50%);z-index:10;text-align:left}
header .appmenu summary{padding:4px 12px;font-size:20px;line-height:1.3}
/* 제목줄 왼쪽 프로젝트 버튼 (☰와 같은 메뉴 모양) */
header .projmenu{position:absolute;left:12px;top:50%;transform:translateY(-50%);z-index:10;text-align:left}
header .projmenu summary{display:flex;align-items:center;gap:6px;padding:5px 12px;font-weight:600}
header .projmenu .menu{min-width:220px}
header .projmenu .menu .h{color:var(--dim);font-size:12px;padding:6px 10px 2px}
header .projmenu .menu button{justify-content:flex-start;align-items:center}
header .projmenu .dot{width:11px;height:11px;border-radius:50%;border:1px solid var(--dim);flex:none}
header .projmenu button.on{background:var(--hover)}
header .projmenu button.on .dot{border:3px solid var(--accent)}
header .projmenu button:disabled{color:var(--dim);cursor:default}
.asktext{display:flex;gap:8px;align-items:center;margin:8px 0 14px;color:var(--dim)}
.asktext input{flex:1;min-width:220px;background:var(--bg);border:1px solid var(--line);border-radius:4px;padding:5px 8px;color:var(--text)}
.newproj .pick{display:flex;gap:10px;align-items:center}
.newproj .chosen{margin:6px 0 14px;font-size:12px;min-height:1em}
header .appmenu .menu{min-width:190px}
.updatebar{flex:none;border:0;border-radius:0;padding:8px 12px;background:var(--accent);color:#fff;font-weight:600;cursor:pointer}
header .appmenu .menu .h{color:var(--dim);font-size:12px;padding:6px 10px 2px}
header .appmenu .menu button{justify-content:flex-start;align-items:center}
header .appmenu .dot{width:11px;height:11px;border-radius:50%;border:1px solid var(--dim);flex:none}
header .appmenu button.on{background:var(--hover)}
header .appmenu button.on .dot{border:3px solid var(--accent)}
/* 가운데 작업 영역 양옆에 광고 자리. 화면이 좁으면 표 자리를 우선한다 */
.layout{flex:1;min-height:0;display:flex}
.work{flex:1;min-width:0;display:flex;flex-direction:column;border-left:1px solid var(--line);border-right:1px solid var(--line)}
/* 양옆 여백(광고 자리): 20 / 60 / 20. 1100 이상이면 양옆이 220px 넘게 남아 160×600 광고가, 1500 이상이면 300×600 광고가 들어간다 */
.side{flex:none;width:20vw}
/* 좁은 화면: 광고는 못 넣지만 여백은 조금 남겨 표 영역을 가운데에 둔다 */
@media (max-width:1100px){.side{width:clamp(16px,5vw,60px)}}
.toolbar{display:flex;gap:8px;align-items:center;padding:8px 12px;flex-wrap:wrap}
.spacer{flex:1}
#status{color:var(--dim)}
#status.bad{color:var(--badline)}
#tabs{display:flex;gap:2px;align-items:flex-end;padding:8px 12px 0;border-bottom:1px solid var(--line);overflow-x:auto;overflow-y:hidden;flex:none}
/* 선택한 탭만 회색으로 채우고, 나머지는 어둡게 */
.tab{display:flex;align-items:center;gap:2px;padding:5px 6px 5px 12px;border:1px solid var(--line);border-bottom:0;border-radius:6px 6px 0 0;background:var(--bg);color:var(--dim);cursor:pointer;white-space:nowrap}
.tab:hover{color:var(--text)}
.tab.on{background:var(--panel);color:var(--text);font-weight:600}
/* 탭을 끌 때 놓을 자리 (TabDrag.js) */
.tab.dropL{box-shadow:inset 3px 0 var(--accent)}
.tab.dropR{box-shadow:inset -3px 0 var(--accent)}
.tab input{width:120px;background:var(--bg);border:1px solid var(--accent);border-radius:3px;padding:0 4px}
#addTab{margin:0 0 3px 4px}
main{flex:1;overflow:auto}
/* 테두리는 칸마다 오른쪽·아래를 직접 갖는다(separate). collapse로 이웃 칸과 함께 그리면, 위·왼쪽에 붙어 있는(sticky)
   머리 칸이 따라와도 테두리 선은 아래 내용과 함께 스크롤돼서 그 1px 틈으로 아래 글자가 비친다 */
table{border-collapse:separate;border-spacing:0}
th,td{border:0 solid var(--line);border-width:0 1px 1px 0;padding:0;white-space:nowrap;background:var(--cell)}
tr>:first-child{border-left-width:1px}
thead tr:first-child>*{border-top-width:1px}
thead th{position:sticky;top:0;z-index:1;background:var(--head)}
thead tr.htype th{top:var(--h1,33px)} /* 타입 행은 이름 행 바로 아래에 붙는다 (GridView.stickHeads) */
th.bad{box-shadow:inset 0 -2px var(--badline)}
/* 컬럼 머리는 이름 칸·타입 칸 두 개 (가로 보기는 두 행, 세로 보기는 두 열). 이름 칸은 글자 길이에 맞춰 늘어나서(field-sizing)
   긴 이름이면 그만큼 열이 넓어진다 (엑셀처럼 손으로 맞출 필요 없게). field-sizing을 모르는 브라우저는 최소 너비로 */
.col{display:flex;gap:4px;align-items:center;padding:4px 6px}
.col .cname{flex:1;min-width:80px;field-sizing:content;background:transparent;border:1px solid transparent;border-radius:3px;padding:2px 4px;font-weight:600}
.col [data-delcol]{margin-left:auto}
.col .cname:focus{border-color:var(--accent);outline:0}
.col select,.col .prefix{background:var(--bg);border:1px solid var(--line);border-radius:3px;padding:1px 4px;color:var(--dim)}
.col .prefix{width:80px}
.enumlist{margin:0;padding:0;list-style:none;display:grid;gap:2px;max-height:240px;overflow:auto}
.enumlist li{padding:3px 8px;background:var(--bg);border-radius:3px}
.opt .pop .dim{color:var(--dim)}
.opt{position:relative}
.opt summary{list-style:none;cursor:pointer}
.opt summary::-webkit-details-marker{display:none}
.opt summary.set{color:var(--accent)}
.opt .pop{position:absolute;left:0;top:calc(100% + 6px);z-index:5;display:grid;gap:8px;white-space:nowrap;font-weight:400;background:var(--panel);border:1px solid var(--line);border-radius:6px;padding:10px 12px;box-shadow:0 6px 16px var(--shadow)}
.opt .pop label{display:flex;gap:6px;align-items:center;color:var(--dim);cursor:pointer}
.opt .pop .refs{display:grid;gap:4px;padding-left:22px} /* 참조할 테이블 체크 목록 */
.ico{padding:0 5px;background:transparent;border:0;color:var(--dim)}
.ico:hover{color:var(--text);background:var(--hover)}
.ico.sort{font-size:11px;color:var(--text)}
td input:not([type]){width:100%;min-width:130px;background:transparent;border:0;padding:6px 8px}
td input:focus{outline:2px solid var(--accent);outline-offset:-2px}
/* 칸 상태: 고른 상태는 커서 없이 테두리만, 수정 상태(더블클릭·F2)는 테두리 색이 다르다 (GridView '칸 상태') */
td input[data-mode="select"]{caret-color:transparent;cursor:cell}
td input[data-mode="edit"]:focus{outline-color:var(--warntext)}
/* ID 칸은 접두사(item_) 자리와 입력칸이 나뉘어 있어서, 테두리를 입력칸이 아니라 칸 전체에 그린다 */
td:has(.idbox) input:focus{outline:0}
td:has(.idbox):focus-within{outline:2px solid var(--accent);outline-offset:-2px}
td:has(.idbox input[data-mode="edit"]:focus){outline-color:var(--warntext)}
/* 드래그·Shift로 고른 범위 */
/* 고른 범위는 칸 색 위에 파랗게 덮는다 (빨간 오류 칸·노란 경고 칸도 골랐는지 보이게) */
td.insel{position:relative}
/* 열·행을 통째로 고르면 그 열의 이름·타입 칸, 그 행의 번호 칸도 파랗게 (엑셀처럼) */
#grid th.hsel,#grid td.num.hsel,#grid.flip th.colhead.hsel{background:color-mix(in srgb,var(--accent) 28%,var(--head))}
td.insel::after{content:'';position:absolute;inset:0;background:var(--accent-tint);pointer-events:none}
#grid tr.pad td{border:0;background:transparent}
#grid:focus{outline:0} /* 스크롤로 치워진 커서를 잠시 맡아 두는 동안 */
td.insel input{cursor:cell}
/* 열 순서 바꾸기: 든 열은 흐리게, 끼울 자리는 파란 선 */
#grid .lift{opacity:.4}
.hint{position:fixed;display:none;pointer-events:none;z-index:20;white-space:pre;color:var(--dim)}
.hint i{font-style:normal;visibility:hidden}
.moveline{position:fixed;display:none;background:var(--accent);pointer-events:none;z-index:20;border-radius:2px}
body.colmove .moveline{display:block}
body.colmove, body.colmove *{cursor:grabbing !important}
.idbox{display:flex;align-items:center}
.idbox .pre{color:var(--dim);padding-left:8px}
.idbox input:not([type]){min-width:70px;padding-left:1px}
td.chk{text-align:left;padding-left:8px;cursor:cell}
td.chk:focus-within{outline:2px solid var(--accent);outline-offset:-2px} /* 고른 Bool 칸은 다른 칸처럼 칸 전체에 테두리 */
td.chk input:focus{outline:0}
td.linked input{color:var(--dim);cursor:default}
.link{display:flex;align-items:center;padding:2px 4px;border-radius:3px}
.link.on,.link.on:hover{color:var(--accent);background:var(--accent-tint)}
.opt .pop select{background:var(--bg);border:1px solid var(--line);border-radius:3px;padding:2px 4px}
td.bad{background:var(--bad)}
td.warn{background:var(--warnbg)}
/* 우클릭 메뉴 (노란 경고 칸의 '이 경고 숨기기') */
.ctxmenu{position:fixed;z-index:40;background:var(--panel);border:1px solid var(--line);border-radius:6px;padding:4px;box-shadow:0 6px 16px var(--shadow)}
.ctxmenu button{display:block;width:100%;text-align:left;background:transparent;border:0;padding:7px 12px;white-space:nowrap}
.ctxmenu button:hover{background:var(--hover)}
#status.warn{color:var(--warntext)}
/* 잠깐 떴다 흐려지는 알림 (Toast.js). 줄바꿈(\n)은 그대로 줄을 나눈다 */
.toast{position:fixed;left:50%;bottom:40px;z-index:60;max-width:min(720px,calc(100vw - 32px));padding:10px 16px;border-radius:8px;
  background:var(--panel);border:1px solid var(--line);border-left:4px solid var(--accent);box-shadow:0 6px 16px var(--shadow);
  white-space:pre-line;cursor:pointer;animation:toast var(--dur) ease forwards}
.toast.warn{border-left-color:var(--warntext)}
.toast.bad{border-left-color:var(--badline)}
.toast:hover{animation-play-state:paused}
@keyframes toast{0%{opacity:0;transform:translate(-50%,8px)}5%,75%{opacity:1;transform:translate(-50%,0)}100%{opacity:0;transform:translate(-50%,0)}}
.ghost{background:transparent;border-style:dashed}
thead th.ghost{background:var(--panel)}
.ghost input::placeholder{color:var(--dim)}
td.ghost input{min-width:100px}
.ghostrow td{background:transparent;border-style:dashed}
/* 모서리 버튼 둘(⇄, 타입 줄 접기)은 같은 크기로 나란히 가운데 */
th.corner{padding:0 4px}
.cornerbtns{display:flex;justify-content:center;align-items:center;gap:2px}
.cbtn{width:28px;height:24px;padding:0;font-size:15px;line-height:1;border-radius:3px}
.cbtn.on{color:var(--accent);background:var(--accent-tint)}
#typeToggle{font-size:20px} /* « ︽ 글자는 ⇄보다 작게 그려져서 키워 맞춘다 */
/* 세로 보기: 왼쪽 컬럼 머리칸을 고정, 맨 오른쪽 새 행 칸은 점선 */
#grid.flip th.colhead{position:sticky;left:0;z-index:2;background:var(--head);text-align:left}
#grid.flip thead th.corner{left:0;z-index:3}
#grid.flip th.tcol{left:var(--w1,52px)} /* 타입 열은 이름 열 바로 오른쪽에 붙는다 */
#grid.flip thead th.tcol{position:sticky;z-index:3}
#grid.notype tr.htype,#grid.notype .tcol{display:none} /* ⇄ 옆 버튼으로 타입 줄 접기 */
.namedel{display:none}
#grid.notype .namedel{display:inline-block} /* 타입 줄을 접으면 열 삭제 ✕는 이름 칸 오른쪽 끝에 */
/* 머리 칸들은 위·왼쪽에 붙어 있어(sticky) 서로 겹쳐 그려진다. ⚙ 창을 연 칸은 맨 위로 올려 다음 칸에 가리지 않게 (위 z-index들보다 뒤에 둔다) */
#grid th:has(.opt[open]){z-index:5}
#grid.flip th.rowhead{color:var(--dim);font-weight:400;min-width:130px}
#grid.flip tr:hover th.rowhead .del{visibility:hidden}
#grid.flip tr:hover th.rowhead:hover .del{visibility:visible}
td:has([data-ghostrow]),th.ghostcell{background:transparent;border-style:dashed}
/* 표 안은 모두 왼쪽 정렬 (글자 시작선이 한 줄로 맞게). 모서리 ⇄ 버튼만 가운데 */
.num{width:52px;text-align:left;color:var(--dim);padding:0 8px}
/* 머리(컬럼 이름·타입 줄, 행 번호, 세로 보기의 이름·타입 열)는 값 칸과 확실히 다른 색, 값 칸과 닿는 쪽은 굵은 선 */
#grid td.num{background:var(--head)}
#grid thead tr:last-child th{border-bottom:2px solid var(--headline)}
#grid.flip th.colhead.tcol,#grid.flip.notype th.colhead:not(.tcol){border-right:2px solid var(--headline)}
#grid:not(.flip) td.num{border-right:2px solid var(--headline)}
th.corner{text-align:center}
.num .del{margin-left:4px}
.num .del{visibility:hidden}
tr:hover .num .del{visibility:visible}
.toolbar button.on{border-color:var(--accent);color:var(--accent)}
/* 불러오기 · 파일 저장: 버튼을 누르면 목록이 열린다 */
.dropmenu{position:relative}
.dropmenu summary{list-style:none;cursor:pointer;background:var(--btn);border:1px solid var(--line);border-radius:4px;padding:4px 10px}
.dropmenu summary:hover{background:var(--hover)}
.dropmenu.primary summary{background:var(--accent);border-color:var(--accent);color:#fff}
/* 불러오기: 파일 저장과 같은 파란 계열이지만 속은 비워서, 채워진 버튼(저장)이 하나만 눈에 띄게 */
.dropmenu.outline summary{background:transparent;border-color:var(--accent);color:var(--accent-text)}
.dropmenu.outline summary:hover{background:var(--accent-tint)}
.dropmenu summary::-webkit-details-marker{display:none}
/* 도구줄 메뉴(불러오기·파일 저장)는 표의 고정 머리 칸(z-index 1~5)보다 위에 */
.dropmenu .menu{position:absolute;right:0;top:calc(100% + 4px);z-index:30;min-width:230px;display:flex;flex-direction:column;background:var(--panel);border:1px solid var(--line);border-radius:6px;padding:4px;box-shadow:0 6px 16px var(--shadow)}
.dropmenu .menu.left{left:0;right:auto}
.dropmenu .menu button{display:flex;justify-content:space-between;gap:12px;background:transparent;border:0;text-align:left;padding:7px 10px;white-space:nowrap}
.dropmenu .menu button:hover,.dropmenu .menu a:hover{background:var(--hover)}
.dropmenu .menu a{display:flex;justify-content:space-between;gap:12px;padding:7px 10px;border-radius:4px;color:var(--text);text-decoration:none;white-space:nowrap}
.dropmenu .menu small{color:var(--dim)}
.dropmenu .menu hr{width:100%;border:0;border-top:1px solid var(--line);margin:4px 0}
.dropmenu .menu .h{color:var(--dim);font-size:12px;padding:6px 10px 2px}
/* 하단 패널: JSON 왼쪽, 테이블 설명 오른쪽. 하나만 열면 전체 폭 */
#panels{height:40vh;display:flex;border-top:1px solid var(--line);background:var(--panel)}
#panels[hidden],#panels section[hidden]{display:none}
#panels section{flex:1;min-width:0;display:flex;flex-direction:column}
#json:not([hidden])+#meta{border-left:1px solid var(--line)}
.bar{display:flex;gap:8px;align-items:center;padding:6px 12px;border-bottom:1px solid var(--line)}
#json pre{flex:1;margin:0;overflow:auto;padding:10px 12px;font:12px/1.5 Consolas,monospace;color:var(--code)}
.metabody{flex:1;overflow:auto;padding:10px 12px}
#tdesc{width:100%;min-height:56px;resize:vertical;background:var(--bg);border:1px solid var(--line);border-radius:4px;padding:6px 8px;margin-bottom:10px}
.metabody table{width:100%}
#cdesc th,#cdesc td{border:0;background:transparent;padding:2px 10px 2px 0;text-align:left}
#cdesc td.t{color:var(--dim)}
/* Enum 목록을 펴면 줄이 길어지니 이름·타입은 위쪽(입력칸 글자 높이)에 맞춘다 */
#cdesc th,#cdesc td{vertical-align:top}
#cdesc th,#cdesc td.t{padding-top:7px}
#cdesc .enumdrop summary{list-style:none;cursor:pointer;white-space:nowrap}
#cdesc .enumdrop summary::-webkit-details-marker{display:none}
#cdesc .enumdrop summary::after{content:' ▾'}
#cdesc .enumdrop[open] summary::after{content:' ▴'}
#cdesc .enumdrop summary:hover{color:var(--text)}
#cdesc .enumdrop .enumlist{margin:4px 0 4px;color:var(--text);max-height:none;overflow:visible}
#cdesc td:last-child{width:100%;padding-right:0}
#cdesc input{width:100%;min-width:160px;background:var(--bg);border:1px solid var(--line);border-radius:4px;padding:4px 6px}
/* 팝업 창 (util.js ask, js/import/SheetPicker.js) */
dialog.popup{background:var(--panel);color:var(--text);border:1px solid var(--line);border-radius:8px;padding:16px 18px;min-width:340px;max-width:90vw;box-shadow:0 10px 30px var(--shadow)}
dialog.popup::backdrop{background:rgba(0,0,0,.4)}
.popup h3{margin:0 0 4px;font-size:15px}
.popup .dim{color:var(--dim)}
.popup p{margin:0 0 10px;white-space:pre-line}
.sheetpick .list{max-height:60vh;overflow:auto;margin-bottom:14px}
.sheetpick table{width:100%}
.sheetpick th,.sheetpick td{padding:5px 10px;text-align:left;vertical-align:middle;background:transparent}
.sheetpick thead th{position:sticky;top:0;background:var(--head);color:var(--dim);font-weight:400;font-size:12px}
.sheetpick tbody tr{cursor:pointer}
.sheetpick tbody tr:hover td{background:var(--hover)}
.sheetpick tr.dim{color:var(--dim);cursor:default}
.sheetpick td:nth-child(3){color:var(--dim);white-space:nowrap}
.sheetpick .rename{background:var(--bg);border:1px solid var(--line);border-radius:3px;padding:2px 6px;color:var(--text);width:180px}
.sheetpick .warn{display:block;color:var(--warntext);margin-top:2px}
.popup .btns{display:flex;justify-content:flex-end;gap:8px}
.donate img{display:block;margin:10px auto;border-radius:6px} /* QR은 흰 바탕째로 그려 다크 테마에서도 찍힌다 */
.donate p{text-align:center}
