:root { --bg:#14171c; --panel:#1c2128; --line:#2d333b; --fg:#d7dde3; --muted:#8b949e; --accent:#4493f8; }
* { box-sizing: border-box; }
body { margin:0; font:14px/1.4 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif; background:var(--bg); color:var(--fg); }

header { display:flex; align-items:center; gap:18px; padding:10px 16px; background:var(--panel); border-bottom:1px solid var(--line); }
header h1 { font-size:16px; margin:0; color:var(--accent); }
.meta { color:var(--muted); font-size:11px; }
.adminlink { margin-left:auto; color:var(--muted); text-decoration:none; font-size:13px; border:1px solid var(--line); border-radius:6px; padding:4px 9px; }
.adminlink:hover { color:var(--fg); background:#21262d; }

/* admin page */
.admin { padding:16px; display:flex; flex-direction:column; gap:16px; max-width:920px; }
.card { background:var(--panel); border:1px solid var(--line); border-radius:10px; padding:14px 16px; }
.card h2 { margin:0 0 10px; font-size:15px; color:var(--accent); }
.card .row { display:flex; gap:10px; margin-top:12px; align-items:center; }
.tbl { width:100%; border-collapse:collapse; margin-top:12px; font-size:13px; }
.tbl th, .tbl td { text-align:left; padding:6px 8px; border-bottom:1px solid var(--line); }
.tbl button { background:#b62324; color:#fff; border:0; border-radius:5px; padding:3px 9px; cursor:pointer; }
#archives button { background:#30363d; color:#fff; border:1px solid #444c56; border-radius:5px; padding:2px 7px; cursor:pointer; font-size:12px; margin-left:3px; }
#archives button:hover { background:#3d444d; }
#archives button.dl { background:#b62324; border-color:#b62324; }
.pager { margin-top:6px; font-size:12px; display:flex; gap:6px; align-items:center; }
.pager button { background:#30363d; color:var(--fg); border:1px solid var(--line); border-radius:5px; padding:1px 8px; cursor:pointer; }
.pager button:disabled { opacity:.4; cursor:default; }
.loginbox { position:fixed; inset:0; z-index:100; display:flex; align-items:center; justify-content:center; background:var(--bg); }
.loginbox > div { background:var(--panel); border:1px solid var(--line); border-radius:12px; padding:24px 28px; display:flex; flex-direction:column; gap:12px; min-width:280px; }
.loginbox h2 { margin:0; color:var(--accent); font-size:16px; }
.loginbox input { background:#0d1117; color:var(--fg); border:1px solid var(--line); border-radius:6px; padding:9px 11px; font-size:14px; }
.loginbox button { background:var(--accent); color:#fff; border:0; border-radius:6px; padding:9px; cursor:pointer; font-size:14px; }
.importbtn { background:#238636; color:#fff; border:1px solid #2ea043; border-radius:6px; padding:5px 11px; cursor:pointer; font-size:13px; }
.importbtn:hover { background:#2ea043; }
.trainbtn { background:#8957e5; color:#fff; border:1px solid #a371f7; border-radius:6px; padding:5px 11px; cursor:pointer; font-size:13px; }
.trainbtn:hover { background:#a371f7; }
.trainbtn:disabled { opacity:.6; cursor:default; }
.modelbtn { background:#1f6feb; color:#fff; border:1px solid #388bfd; border-radius:6px; padding:5px 11px; cursor:pointer; font-size:13px; }
.modelbtn:hover { background:#388bfd; }

#controls { display:flex; flex-wrap:wrap; gap:18px; padding:10px 16px; background:var(--panel); border-bottom:1px solid var(--line); align-items:center; }
label { display:flex; flex-direction:column; gap:3px; font-size:12px; color:var(--muted); }
label.chk { flex-direction:row; align-items:center; gap:6px; color:var(--fg); }
select, input[type=range] { accent-color:var(--accent); }
select { background:#0d1117; color:var(--fg); border:1px solid var(--line); border-radius:6px; padding:4px 6px; }
input[type=range] { width:150px; }
output { color:var(--fg); font-variant-numeric:tabular-nums; }

/* viewer = single-screen app (no page scroll); admin pages are unaffected.
   position:fixed + inset:0 pins the shell to the TRUE visible viewport box on every
   environment (browser chrome, OS zoom, Electron insets) — vh/dvh can over-report and
   push the bottom status bar under the fold; this never does. */
body.viewer { position:fixed; inset:0; overflow:hidden; display:flex; flex-direction:column;
              user-select:none; -webkit-user-select:none; }
body.viewer img { -webkit-user-drag:none; user-drag:none; }
body.viewer > #appbar, body.viewer > #ribbon, body.viewer > .ctrlsec, body.viewer > #statusbar { flex:none; }
body.viewer > #stage { flex:1; min-height:0; }

/* ===== app chrome (dark, dense, refined) ===== */
#appbar { display:flex; align-items:center; gap:8px; height:26px; padding:0 8px;
          background:linear-gradient(#20262e,#191e24); border-bottom:1px solid var(--line); }
.brand { font-weight:700; font-size:11px; color:var(--accent); letter-spacing:.5px; }
#tabs { display:flex; gap:3px; align-items:center; flex:1; min-width:0; overflow-x:auto; height:100%; }
.tab { display:flex; align-items:center; gap:6px; max-width:170px; height:19px; padding:0 5px 0 9px;
       background:#181c22; border:1px solid var(--line); border-radius:5px; color:var(--muted);
       font-size:10px; cursor:pointer; white-space:nowrap; }
.tab.active { background:#0d1117; color:var(--fg); border-color:var(--accent); }
.tab .name { overflow:hidden; text-overflow:ellipsis; }
.tab .x { color:#6b7280; padding:0 2px; border-radius:4px; } .tab .x:hover { color:#f85149; background:#2d333b; }

.menu { position:relative; }
.menu > summary { list-style:none; cursor:pointer; color:var(--muted); background:#181c22;
                  border:1px solid var(--line); border-radius:6px; padding:3px 8px; font-size:11px; user-select:none; }
.menu > summary::-webkit-details-marker { display:none; }
.menu > summary:hover { color:var(--fg); border-color:var(--accent); }
.menu-list { position:absolute; right:0; top:calc(100% + 5px); z-index:30; min-width:210px; max-height:60vh; overflow:auto;
             background:var(--panel); border:1px solid var(--line); border-radius:8px; padding:6px;
             display:flex; flex-direction:column; gap:2px; box-shadow:0 10px 30px rgba(0,0,0,.5); }
.menu-list button { background:transparent; color:var(--fg); border:0; border-radius:6px; padding:7px 9px;
                    font-size:12px; text-align:left; cursor:pointer; }
.menu-list button:hover { background:#22272e; }
.menu-list .muted { padding:6px 9px; }

.seg { display:flex; background:#0d1117; border:1px solid var(--line); border-radius:6px; padding:1px; }

/* ribbon: group-nav tab row (디스플레이/후처리/AI 검출) + header below */
#ribbon { display:flex; align-items:stretch; gap:10px; height:24px; padding:0 8px;
          background:var(--panel); border-bottom:1px solid var(--line); }
.ribtabs { display:flex; gap:2px; align-items:stretch; }
.ribtab { background:transparent; color:var(--muted); border:0; border-bottom:2px solid transparent;
          padding:0 12px; font-size:11px; cursor:pointer; }
.ribtab:hover { color:var(--fg); }
.ribtab.active { color:var(--fg); border-bottom-color:var(--accent); }
#ribbon #meta { margin-left:auto; align-self:center; max-width:34ch; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.tabview { display:contents; }          /* groups become direct flex items of the header */
.tabview[hidden] { display:none; }
/* icon buttons (열기 / import) — standard line icons */
.iconbtn { line-height:0; }
.iconbtn svg { display:block; }
#appbar .iconbtn, #appbar .importbtn.iconbtn { padding:3px 7px; background:transparent; border:1px solid var(--line); border-radius:6px; color:var(--muted); }
#appbar .iconbtn:hover, #appbar .importbtn.iconbtn:hover { color:var(--fg); background:#21262d; }

.ctrlsec { display:flex; flex-wrap:wrap; gap:10px; align-items:center; padding:3px 10px;
           background:#171b21; border-bottom:1px solid var(--line); }
.grp { display:flex; flex-wrap:wrap; gap:9px; align-items:center; padding-right:10px; border-right:1px solid var(--line); }
.grp:last-child { border-right:0; padding-right:0; }
.grplabel { font-size:9px; font-weight:600; letter-spacing:.5px; text-transform:uppercase; color:var(--muted); }

/* refined controls — scoped to the chrome so the admin page keeps its styles */
.ctrlsec label { display:flex; flex-direction:row; align-items:center; gap:5px; font-size:10px; color:var(--muted); }
/* control header = FIXED height so switching ribbon tabs never shifts the layout */
#ribbon-body { height:38px; overflow:hidden; flex-wrap:nowrap; }
.ctrlsec label.chk { flex-direction:row; align-items:center; gap:6px; color:var(--fg); font-size:12px; }
.ctrlsec output { color:var(--fg); font-variant-numeric:tabular-nums; font-size:11px; }
.ctrlsec select, .ctrlsec input[type=number] { background:#0d1117; color:var(--fg); border:1px solid var(--line); border-radius:6px; padding:4px 8px; font-size:12px; }
.ctrlsec input[type=range] { -webkit-appearance:none; appearance:none; width:120px; height:4px; border-radius:3px; background:#30363d; outline:none; }
.ctrlsec input[type=range]::-webkit-slider-thumb { -webkit-appearance:none; width:13px; height:13px; border-radius:50%; background:var(--accent); cursor:pointer; border:2px solid #0d1117; }
.ctrlsec input[type=range]::-moz-range-thumb { width:13px; height:13px; border-radius:50%; background:var(--accent); cursor:pointer; border:2px solid #0d1117; }
.ctrlsec input[type=checkbox] { accent-color:var(--accent); width:15px; height:15px; }
.btn { background:#21262d; color:var(--fg); border:1px solid var(--line); border-radius:7px; padding:6px 13px; font-size:12px; cursor:pointer; }
.btn:hover { border-color:var(--accent); }
.btn.primary { background:var(--accent); border-color:var(--accent); color:#fff; }
.btn.primary:hover { background:#3b86f0; }
.btn:disabled { opacity:.55; cursor:default; }

#stage { display:flex; align-items:stretch; }
/* cursor/box tools live in the ribbon (segmented) */
#tools { display:flex; align-self:center; }
.tool { background:transparent; color:var(--muted); border:0; border-radius:5px; padding:1px 8px; font-size:13px; line-height:1; cursor:pointer; }
.tool:not(.active):hover { color:var(--fg); }
.tool.active { background:var(--accent); color:#fff; }
/* app-style bottom status bar (single global readout, full width) */
#statusbar { height:20px; display:flex; align-items:center; justify-content:flex-end; padding:0 30px; gap:14px;
             background:var(--panel); border-top:1px solid var(--line); color:var(--muted);
             font-size:10px; font-variant-numeric:tabular-nums; white-space:nowrap; overflow:hidden; }
/* control-panel layout: two columns of stacked panels that FILL the viewport
   (no page scroll). Draggable gutters redistribute space between neighbors —
   shrink one, the next grows. SinkholeFinder's "everything at a glance" feel. */
#panels { flex:1; min-width:0; min-height:0; display:flex; height:100%; overflow:hidden; padding:3px; gap:0; }
.col { flex:1 1 0; display:flex; flex-direction:column; min-width:0; min-height:0; overflow:hidden; }
body[data-tool="cursor"] .overlay { cursor:grab; }
body[data-tool="box"] .overlay { cursor:crosshair; }
.panel { flex:1 1 0; min-width:0; min-height:0; margin:0; background:var(--panel);
         border:1px solid var(--line); border-radius:5px; overflow:hidden;
         display:flex; flex-direction:column; }
.gutter { flex:none; background:transparent; }
.gutter.h { height:6px; cursor:row-resize; }
.gutter.v { width:6px; cursor:col-resize; }
.gutter:hover { background:var(--accent); }
figcaption { display:flex; align-items:center; gap:6px; padding:2px 7px; font-size:10px; color:var(--fg); border-bottom:1px solid var(--line); }
#appbar .importbtn { padding:3px 8px; font-size:11px; }
figcaption .sel { flex:1; max-width:480px; }
figcaption .idx { color:var(--accent); font-variant-numeric:tabular-nums; min-width:3ch; display:inline-block; }
/* section plot = image with axis rulers (줄자): [Y축 | 영상] over [모서리 | X축] */
/* minmax(0,…) so the image track can't push the ruler strips out of view on short panels */
.plot { flex:1; min-height:0; min-width:0; display:grid;
        grid-template-columns:44px minmax(0,1fr); grid-template-rows:minmax(0,1fr) 20px; background:var(--panel); }
.axisX, .axisY { display:block; width:100%; height:100%; }
.axiscorner { background:var(--panel); }
.imgwrap { background:#000; line-height:0; overflow:hidden; position:relative; min-height:0; min-width:0; }
.imgwrap canvas.glview { display:block; width:100%; height:100%; }   /* fills the widget body */
.overlay { position:absolute; left:0; top:0; cursor:crosshair; touch-action:none; background:transparent; }

.anno { margin-left:auto; display:flex; gap:8px; align-items:center; }
.anno select { background:#0d1117; color:var(--fg); border:1px solid var(--line); border-radius:6px; padding:3px 5px; font-size:12px; }
.anno button { background:#30363d; color:var(--fg); border:1px solid var(--line); border-radius:6px; padding:3px 8px; font-size:12px; cursor:pointer; }
.anno button:hover { background:#3d444d; }
.anno button.ai { background:#1f6feb; border-color:#1f6feb; }
.anno button.ai:hover { background:#388bfd; }
.anno button:disabled { opacity:.6; cursor:default; }

.zoomreset { background:#30363d; color:var(--fg); border:1px solid var(--line); border-radius:6px; padding:1px 7px; font-size:12px; cursor:pointer; }
.zoomreset:hover { background:#3d444d; }

.muted { color:var(--muted); font-size:12px; font-weight:normal; }
.panel > canvas { display:block; width:100%; flex:1; min-height:0; background:#0d1117; }

/* widget chrome: close (✕), scale readout, and the ➕위젯 add-menu */
.wclose { order:99; margin-left:auto; background:transparent; color:var(--muted); border:0;
          cursor:pointer; font-size:13px; line-height:1; padding:0 2px; }
.wclose:hover { color:#f0f6fc; }
.addw { position:relative; }
.addw > summary { list-style:none; cursor:pointer; color:var(--muted); border:1px solid var(--line);
                  border-radius:5px; padding:1px 8px; font-size:10px; user-select:none; }
.addw > summary::-webkit-details-marker { display:none; }
.addw > summary:hover { color:var(--fg); background:#21262d; }
.addw-list { position:absolute; right:0; top:calc(100% + 4px); z-index:20; min-width:200px;
             background:var(--panel); border:1px solid var(--line); border-radius:8px; padding:6px;
             display:flex; flex-direction:column; gap:4px; box-shadow:0 8px 24px rgba(0,0,0,.45); }
.addw-list button { background:#21262d; color:var(--fg); border:1px solid var(--line); border-radius:6px;
                    padding:6px 9px; font-size:12px; text-align:left; cursor:pointer; }
.addw-list button:hover { background:#30363d; }

/* 3D volume widget */
.vol3dbar { display:flex; gap:10px; align-items:center; padding:8px 12px; flex:none; }
.vol3dcanvas { flex:1; min-height:0; width:100%; background:#0d1117; overflow:hidden; }
.vol3dcanvas canvas { display:block; }

/* sidecar media widgets (video / map) — fill the widget body */
.videobox { flex:1; min-height:0; width:100%; background:#000; display:block; object-fit:cover; }
.roadwrap { position:relative; min-width:0; min-height:0; overflow:hidden; background:#000; line-height:0; }
.roadbox { height:100%; display:block; object-fit:fill; }   /* width/transform set by JS to track the planes' viewport */
.mapbox { flex:1; min-height:0; width:100%; }
.mapbox .leaflet-container { width:100%; height:100%; background:#0d1117; }

/* native-style right-click menu */
.ctxmenu { position:fixed; z-index:1000; background:#161b22; border:1px solid #30363d; border-radius:6px;
  padding:4px; box-shadow:0 6px 20px rgba(0,0,0,.5); min-width:150px; }
.ctxmenu button { display:block; width:100%; text-align:left; background:none; border:0; color:#e6edf3;
  font-size:12px; padding:6px 10px; border-radius:4px; cursor:pointer; }
.ctxmenu button:hover { background:#1f6feb; }

/* AI 설정 mini-panel */
.aibody { padding:10px 12px; display:flex; flex-direction:column; gap:10px; overflow:auto; }
.airow { display:grid; grid-template-columns:1fr 110px 38px; align-items:center; gap:8px;
         font-size:12px; color:var(--muted); }
.airow input[type=range] { width:100%; accent-color:var(--accent); }
.airow output { color:var(--fg); font-variant-numeric:tabular-nums; text-align:right; }
.aiallbtn { align-self:flex-start; background:#1f6feb; color:#fff; border:1px solid #388bfd;
            border-radius:6px; padding:6px 11px; font-size:13px; cursor:pointer; }
.aiallbtn:hover { background:#388bfd; }
.aiallbtn:disabled { opacity:.6; cursor:default; }
.aires { display:flex; flex-wrap:wrap; gap:6px; align-items:center; }
.aichip { background:#21262d; color:var(--fg); border:1px solid var(--line); border-radius:6px;
          padding:3px 8px; font-size:12px; cursor:pointer; }
.aichip:hover { background:#30363d; border-color:var(--accent); }

/* 전체 채널 추론 결과 floating window (control bar is fixed-height -> chips were clipped) */
.aiwin { position:fixed; right:16px; bottom:28px; z-index:900; width:300px; max-height:55vh;
         display:flex; flex-direction:column; background:#161b22; border:1px solid #30363d;
         border-radius:8px; box-shadow:0 12px 32px rgba(0,0,0,.55); overflow:hidden; }
.aiwin-bar { display:flex; align-items:center; gap:8px; padding:6px 10px; background:#1f2733;
             border-bottom:1px solid #30363d; cursor:move; user-select:none; }
.aiwin-title { font-size:12px; color:var(--fg); font-weight:600; }
.aiwin-prog { font-size:11px; }
.aiwin-x { margin-left:auto; background:transparent; border:0; color:var(--muted); cursor:pointer; font-size:13px; }
.aiwin-x:hover { color:#f85149; }
.aiwin-body { display:flex; flex-wrap:wrap; gap:6px; padding:10px; overflow:auto; min-height:40px; }

/* drag-and-drop import overlay (folder drop pulls the .t3h automatically) */
#dropzone { position:fixed; inset:12px; z-index:50; display:none; align-items:center; justify-content:center;
            background:rgba(13,17,23,.82); color:var(--fg); font-size:18px; pointer-events:none;
            border:3px dashed var(--accent); border-radius:14px; }
#dropzone.on { display:flex; }
