/* Dihasilkan oleh alat/lingkup-css.py — jangan disunting tangan. */
/* Token Geo dipetakan ke token tema SI-BERSINAR (aset/tema.css).
   --ok dan --font sengaja TIDAK ditulis di sini: namanya sama di kedua
   tema, jadi keduanya cukup diwarisi dari :root. */
.geo{
  --bg:var(--kanvas);--bg2:var(--permukaan);--bg3:var(--lembut);
  --glass:var(--kaca);--glass2:var(--kaca2);
  --line:var(--garis);--line2:var(--garis-kuat);
  --fg:var(--teks);--fg2:var(--teks-2);--muted:var(--teks-3);
  --acc:var(--utama);--acc2:var(--utama-sentuh);
  --warn:var(--awas);--err:var(--bahaya);
  --rail:60px;--panel:360px;--radius:var(--r-md);--sh:var(--bayang-lg);
}
.geo, .geo *{box-sizing:border-box}
.geo{height:100%;margin:0;background:var(--bg);color:var(--fg);font:13px/1.45 var(--font);overflow:hidden}
.geo button, .geo input, .geo select, .geo textarea{font:inherit;color:inherit}
.geo button{cursor:pointer}
.geo{position:relative;width:100vw;height:100vh;overflow:hidden}
.geo #map{position:absolute;inset:0;background:var(--peta-latar)}
.geo .maplibregl-ctrl-attrib{background:var(--kaca)!important;color:var(--teks-3);font-size:10px}
.geo .maplibregl-ctrl-attrib a{color:var(--utama)}
.geo .maplibregl-ctrl-bottom-right{right:0;bottom:calc(26px + var(--dock-h,0px))}
.geo .maplibregl-ctrl-bottom-left{left:var(--rail);bottom:calc(26px + var(--dock-h,0px))}
.geo .maplibregl-ctrl-bottom-left .maplibregl-ctrl{margin:0 0 6px 14px}
.geo .maplibregl-ctrl-scale{background:var(--kaca)!important;border-color:var(--teks)!important;color:var(--teks)!important;font-size:10px!important}
.geo .maplibregl-popup-content{background:var(--glass2);color:var(--fg);border-radius:10px;box-shadow:var(--sh);padding:10px 12px;font:12px/1.4 var(--font);max-width:340px;border:1px solid var(--line2)}
.geo .maplibregl-popup-anchor-bottom .maplibregl-popup-tip{border-top-color:var(--glass2)}
.geo .maplibregl-popup-anchor-top .maplibregl-popup-tip{border-bottom-color:var(--glass2)}
.geo .maplibregl-popup-anchor-left .maplibregl-popup-tip{border-right-color:var(--glass2)}
.geo .maplibregl-popup-anchor-right .maplibregl-popup-tip{border-left-color:var(--glass2)}
.geo .maplibregl-popup-close-button{color:var(--fg2);font-size:18px;padding:2px 8px}
.geo .maplibregl-popup-close-button:hover{background:transparent;color:var(--teks)}
.geo .maplibregl-canvas:focus{outline:none}

/* ---------- rail ---------- */
.geo #rail{position:absolute;left:0;top:0;bottom:0;width:var(--rail);background:var(--glass);backdrop-filter:blur(14px);border-right:1px solid var(--line);display:flex;flex-direction:column;align-items:stretch;padding:8px 0 30px;z-index:20}
.geo .rail-logo{display:flex;align-items:center;justify-content:center;height:44px;margin-bottom:6px}
.geo .rail-btn{background:transparent;border:0;color:var(--fg2);display:flex;flex-direction:column;align-items:center;gap:3px;padding:8px 0 7px;margin:1px 6px;border-radius:10px;font-size:10px;letter-spacing:.2px}
.geo .rail-btn svg{width:21px;height:21px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.geo .rail-btn:hover{background:rgba(11,33,23,.045);color:var(--teks)}
.geo .rail-btn.active{background:rgba(0,111,55,.11);color:var(--acc)}
.geo .rail-spacer{flex:1}

/* ---------- panel ---------- */
.geo #panel{position:absolute;left:var(--rail);top:0;bottom:26px;width:var(--panel);background:var(--glass);backdrop-filter:blur(16px);border-right:1px solid var(--line);z-index:15;display:flex;flex-direction:column;transition:transform .18s ease,opacity .18s ease}
.geo #panel.hidden{transform:translateX(-16px);opacity:0;pointer-events:none}
.geo .panel-head{display:flex;align-items:center;justify-content:space-between;padding:12px 14px 10px 16px;border-bottom:1px solid var(--line)}
.geo .panel-head h2{margin:0;font-size:15px;font-weight:600;letter-spacing:.2px}
.geo .panel-body{flex:1;overflow:auto;padding:12px 14px 16px 16px}
.geo .panel-body::-webkit-scrollbar, .geo .dock-body::-webkit-scrollbar, .geo #search-results::-webkit-scrollbar, .geo .dlg-body::-webkit-scrollbar{width:8px}
.geo .panel-body::-webkit-scrollbar-thumb, .geo .dock-body::-webkit-scrollbar-thumb, .geo #search-results::-webkit-scrollbar-thumb, .geo .dlg-body::-webkit-scrollbar-thumb{background:rgba(11,33,23,.14);border-radius:8px}
.geo .icon-btn{background:transparent;border:0;color:var(--fg2);font-size:20px;line-height:1;width:30px;height:30px;border-radius:8px;display:inline-flex;align-items:center;justify-content:center}
.geo .icon-btn:hover{background:rgba(11,33,23,.05);color:var(--teks)}
.geo .icon-btn svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.geo .muted{color:var(--muted)}
.geo .small{font-size:11.5px}
.geo h3.sec{margin:14px 0 8px;font-size:11px;text-transform:uppercase;letter-spacing:.8px;color:var(--muted);font-weight:600}
.geo h3.sec:first-child{margin-top:2px}
.geo p.help{margin:0 0 10px;color:var(--fg2);font-size:12px}

/* ---------- buttons ---------- */
.geo .btn{background:var(--bg3);border:1px solid var(--line2);color:var(--fg);border-radius:9px;padding:8px 12px;font-size:12.5px;display:inline-flex;align-items:center;gap:7px;line-height:1.2;white-space:nowrap}
.geo .btn:hover{background:var(--lembut);border-color:var(--garis-kuat)}
.geo .btn.primary{background:var(--acc2);border-color:var(--acc2);color:var(--utama-isi-teks);font-weight:600}
.geo .btn.primary:hover{background:var(--utama-gelap)}
.geo .btn.danger{color:var(--bahaya);border-color:var(--bahaya-garis)}
.geo .btn.sm{padding:5px 9px;font-size:11.5px;border-radius:7px}
.geo .btn.block{width:100%;justify-content:flex-start}
.geo .btn:disabled{opacity:.45;cursor:not-allowed}
.geo .btn svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.geo .tool-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.geo .tool-card{background:rgba(11,33,23,.03);border:1px solid var(--line);border-radius:10px;padding:10px 11px;text-align:left;display:flex;flex-direction:column;gap:4px;min-height:64px}
.geo .tool-card:hover{background:rgba(0,111,55,.07);border-color:rgba(0,111,55,.3)}
.geo .tool-card b{font-weight:600;font-size:12.5px}
.geo .tool-card span{color:var(--muted);font-size:11px;line-height:1.35}
.geo .row{display:flex;gap:8px;align-items:center}
.geo .row.wrap{flex-wrap:wrap}
.geo .row > *{min-width:0}
.geo .grow{flex:1}

/* ---------- inputs ---------- */
.geo .field{display:flex;flex-direction:column;gap:5px;margin-bottom:11px}
.geo .field label{font-size:11.5px;color:var(--fg2)}
.geo .field .hint{font-size:11px;color:var(--muted)}
.geo input[type=text], .geo input[type=number], .geo input[type=search], .geo select, .geo textarea{background:var(--permukaan);border:1px solid var(--line2);border-radius:8px;padding:7px 9px;color:var(--fg);width:100%;outline:none}
.geo input:focus, .geo select:focus, .geo textarea:focus{border-color:var(--acc)}
.geo select option{background:var(--permukaan);color:var(--teks)}
.geo textarea{min-height:76px;resize:vertical;font-family:ui-monospace,Consolas,monospace;font-size:12px}
.geo input[type=color]{width:38px;height:30px;padding:0;border:1px solid var(--line2);border-radius:7px;background:transparent}
.geo input[type=range]{width:100%;accent-color:var(--acc)}
.geo input[type=checkbox]{accent-color:var(--acc);width:15px;height:15px}
.geo .check{display:flex;align-items:center;gap:8px;font-size:12.5px;color:var(--fg)}
.geo .check-grid{display:grid;grid-template-columns:1fr 1fr;gap:5px 12px}
.geo .check-grid.one{grid-template-columns:1fr}
.geo .check-grid .check{font-size:12px}
.geo .inline2{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.geo .inline3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:8px}
.geo .coord-row{display:grid;grid-template-columns:1fr 1fr auto;gap:6px;align-items:center}

/* ---------- search ---------- */
.geo #searchbox{position:absolute;left:calc(var(--rail) + 14px);top:12px;width:400px;max-width:calc(100vw - var(--rail) - 100px);background:var(--glass);backdrop-filter:blur(14px);border:1px solid var(--line2);border-radius:14px;box-shadow:var(--sh);z-index:18;display:flex;align-items:center;padding:0 8px 0 12px;height:44px}
.geo #searchbox.shifted{left:calc(var(--rail) + var(--panel) + 14px)}
.geo #searchbox svg{width:18px;height:18px;fill:none;stroke:var(--fg2);stroke-width:2;flex:none}
.geo #searchbox input{background:transparent;border:0;flex:1;padding:8px 10px;font-size:14px}
.geo #search-results{position:absolute;left:0;right:0;top:50px;max-height:min(60vh,480px);overflow:auto;background:var(--glass2);border:1px solid var(--line2);border-radius:12px;box-shadow:var(--sh);padding:6px}
.geo .sr-group{padding:6px 10px 3px;font-size:10.5px;text-transform:uppercase;letter-spacing:.7px;color:var(--muted)}
.geo .sr-item{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:8px;cursor:pointer}
.geo .sr-item:hover, .geo .sr-item.active{background:rgba(0,111,55,.09)}
.geo .sr-item .sr-ico{width:28px;height:28px;border-radius:8px;background:rgba(11,33,23,.045);display:flex;align-items:center;justify-content:center;font-size:13px;flex:none}
.geo .sr-item .sr-txt{flex:1;min-width:0}
.geo .sr-item .sr-txt b{display:block;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.geo .sr-item .sr-txt span{display:block;font-size:11px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.geo .sr-item .sr-kind{font-size:10.5px;color:var(--fg2);background:rgba(11,33,23,.045);padding:2px 7px;border-radius:20px;flex:none}
.geo .sr-empty{padding:12px;color:var(--muted);text-align:center}

/* ---------- controls ---------- */
.geo #map-controls{position:absolute;right:12px;bottom:calc(52px + var(--dock-h,0px));display:flex;flex-direction:column;gap:8px;z-index:16;align-items:center}
.geo .ctl{width:40px;height:40px;border-radius:50%;background:var(--glass);backdrop-filter:blur(12px);border:1px solid var(--line2);color:var(--fg);box-shadow:0 4px 14px rgba(11,33,23,.14);display:flex;align-items:center;justify-content:center;font-weight:600;font-size:15px}
.geo .ctl:hover{background:var(--glass2);border-color:rgba(11,33,23,.2)}
.geo .ctl.on{color:var(--acc);border-color:var(--acc)}
.geo .ctl svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.geo .ctl-group{display:flex;flex-direction:column;background:var(--glass);border:1px solid var(--line2);border-radius:22px;overflow:hidden;box-shadow:0 4px 14px rgba(11,33,23,.14)}
.geo .ctl-group .ctl{border:0;border-radius:0;background:transparent;box-shadow:none;height:38px;font-size:19px}
.geo .ctl-group .ctl + .ctl{border-top:1px solid var(--line)}

/* ---------- legend ---------- */
.geo #legend{position:absolute;left:calc(var(--rail) + 14px);bottom:calc(64px + var(--dock-h,0px));width:250px;max-height:44vh;background:var(--glass);backdrop-filter:blur(14px);border:1px solid var(--line2);border-radius:12px;box-shadow:var(--sh);z-index:14;display:flex;flex-direction:column;overflow:hidden;transition:left .18s ease}
.geo #legend.shifted{left:calc(var(--rail) + var(--panel) + 14px)}
.geo #legend.collapsed .legend-body{display:none}
.geo #legend.collapsed .legend-head button{transform:rotate(180deg)}
.geo .legend-head{display:flex;justify-content:space-between;align-items:center;padding:6px 6px 6px 12px;font-weight:600;font-size:12px}
.geo .legend-head .icon-btn{width:24px;height:24px;font-size:14px}
.geo .legend-body{overflow:auto;padding:0 12px 10px}
.geo .lg-layer{margin:6px 0 4px;font-weight:600;font-size:11.5px}
.geo .lg-item{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--fg2);margin:2px 0 2px 2px;min-width:0}
.geo .lg-item > span:not(.lg-sw){overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.geo .lg-sw{width:18px;height:12px;border-radius:3px;flex:none;border:1px solid rgba(11,33,23,.16)}
.geo .lg-sw.line{height:3px;border:0;border-radius:2px}
.geo .lg-sw.pt{width:11px;height:11px;border-radius:50%}
.geo .lg-sw.raster{background:linear-gradient(135deg,#48c 0 50%,#4c8 50%)}
.geo .lg-empty{color:var(--muted);font-size:11.5px;padding:6px 0 4px}

/* ---------- status ---------- */
.geo #statusbar{position:absolute;left:0;right:0;bottom:0;height:26px;background:var(--kaca);border-top:1px solid var(--line);display:flex;align-items:center;gap:18px;padding:0 12px 0 calc(var(--rail) + 12px);font-size:11.5px;color:var(--fg2);z-index:21;font-variant-numeric:tabular-nums;white-space:nowrap}
.geo #statusbar > span{overflow:hidden;text-overflow:ellipsis}
.geo #st-coord{cursor:pointer;min-width:230px}
.geo #st-coord:hover{color:var(--teks)}
.geo .st-spacer{flex:1}
.geo #st-msg{color:var(--acc)}
.geo #st-brand{color:var(--muted)}

/* ---------- layer list ---------- */
.geo .lyr-group{margin-bottom:8px}
.geo .lyr-group-head{display:flex;align-items:center;gap:6px;font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:.7px;padding:6px 2px 4px;cursor:pointer;user-select:none}
.geo .lyr-group-head::before{content:"▾";font-size:10px;transition:transform .15s}
.geo .lyr-group.closed .lyr-group-head::before{transform:rotate(-90deg)}
.geo .lyr-group.closed .lyr-items{display:none}
.geo .lyr{display:flex;align-items:center;gap:8px;padding:6px 6px 6px 4px;border-radius:9px;border:1px solid transparent;margin-bottom:2px;cursor:default}
.geo .lyr:hover{background:rgba(11,33,23,.035)}
.geo .lyr.active{background:rgba(0,111,55,.08);border-color:rgba(0,111,55,.28)}
.geo .lyr.dragover{border-top:2px solid var(--acc)}
.geo .lyr .drag{cursor:grab;color:var(--muted);font-size:14px;width:12px;text-align:center;flex:none}
.geo .lyr .vis{flex:none}
.geo .lyr .sw{width:16px;height:16px;border-radius:4px;border:1px solid rgba(11,33,23,.2);flex:none}
.geo .lyr .sw.line{height:4px;border:0;border-radius:2px}
.geo .lyr .sw.pt{border-radius:50%;width:12px;height:12px;margin:0 2px}
.geo .lyr .name{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:12.5px}
.geo .lyr .name small{display:block;color:var(--muted);font-size:10.5px;line-height:1.2}
.geo .lyr .more{opacity:0;transition:opacity .1s}
.geo .lyr:hover .more, .geo .lyr.active .more{opacity:1}
.geo .lyr.dim .name{color:var(--muted)}
.geo .lyr-toolbar{display:flex;gap:6px;margin-bottom:10px;flex-wrap:wrap}

/* ---------- catalog ---------- */
.geo .cat-item{display:flex;align-items:center;gap:10px;padding:8px 8px;border:1px solid var(--line);border-radius:10px;margin-bottom:6px;background:rgba(11,33,23,.025)}
.geo .cat-item .ico{width:34px;height:34px;border-radius:9px;flex:none;display:flex;align-items:center;justify-content:center;font-size:16px;background:rgba(0,111,55,.09)}
.geo .cat-item .txt{flex:1;min-width:0}
.geo .cat-item .txt b{display:block;font-size:12.5px;font-weight:600;line-height:1.3}
.geo .cat-item .txt span{display:block;font-size:11px;color:var(--muted);line-height:1.35}
.geo .cat-item .btn{flex:none}
.geo .tag{display:inline-block;font-size:10px;padding:1px 6px;border-radius:10px;background:rgba(11,33,23,.05);color:var(--fg2);margin-left:4px;vertical-align:middle}
.geo .tag.on{background:var(--ok-isi);color:var(--ok)}
.geo .tabs{display:flex;gap:4px;margin-bottom:12px;background:var(--lembut);padding:4px;border-radius:10px}
.geo .tabs button{flex:1;background:transparent;border:0;color:var(--fg2);padding:6px 4px;border-radius:7px;font-size:12px}
.geo .tabs button.on{background:var(--permukaan);color:var(--utama);box-shadow:var(--bayang-sm)}

/* ---------- dialog ---------- */
.geo #dialog-root:empty{display:none}
.geo .dlg-backdrop{position:absolute;inset:0;background:rgba(11,33,23,.38);z-index:40;display:flex;align-items:center;justify-content:center;padding:20px}
.geo .dlg-backdrop.minimized{background:transparent;pointer-events:none}
.geo .dlg-backdrop.minimized .dlg{display:none}
.geo .dlg{width:460px;max-width:100%;max-height:calc(100vh - 60px);background:var(--glass2);backdrop-filter:blur(18px);border:1px solid var(--line2);border-radius:16px;box-shadow:0 24px 60px rgba(0,0,0,.6);display:flex;flex-direction:column;pointer-events:auto;animation:pop .16s ease}
.geo .dlg.wide{width:720px}
.geo .dlg.xwide{width:900px}
@keyframes pop{from{transform:scale(.96);opacity:0}to{transform:none;opacity:1}}
.geo .dlg-head{display:flex;align-items:center;gap:10px;padding:14px 14px 10px 18px;border-bottom:1px solid var(--line)}
.geo .dlg-head .dlg-ico{width:32px;height:32px;border-radius:9px;background:rgba(0,111,55,.1);display:flex;align-items:center;justify-content:center;font-size:16px;flex:none}
.geo .dlg-head h3{margin:0;font-size:15px;font-weight:600;flex:1}
.geo .dlg-desc{margin:0;padding:10px 18px 0;color:var(--fg2);font-size:12px}
.geo .dlg-body{padding:14px 18px 6px;overflow:auto}
.geo .dlg-foot{display:flex;justify-content:flex-end;gap:8px;padding:10px 18px 14px;border-top:1px solid var(--line)}
.geo .dlg-foot .left{margin-right:auto;display:flex;gap:8px}
.geo .pick-hint{position:absolute;left:50%;top:14px;transform:translateX(-50%);background:var(--acc2);color:#fff;font-weight:600;padding:9px 16px;border-radius:30px;box-shadow:var(--sh);z-index:45;display:flex;gap:12px;align-items:center;font-size:13px}
.geo .pick-hint button{background:rgba(255,255,255,.28);border:0;color:#fff;border-radius:20px;padding:4px 10px;font-weight:600}
.geo .result-box{background:var(--lembut);border:1px solid var(--line);border-radius:10px;padding:10px 12px;font-size:12.5px;margin-bottom:10px}
.geo .result-box table{width:100%;border-collapse:collapse}
.geo .result-box td{padding:3px 4px;border-bottom:1px solid var(--line);vertical-align:top}
.geo .result-box td:first-child{color:var(--fg2);width:45%}
.geo .kv{display:grid;grid-template-columns:auto 1fr;gap:4px 12px;font-size:12.5px}
.geo .kv div:nth-child(odd){color:var(--fg2)}
.geo .chart{width:100%;height:220px;background:var(--lembut);border-radius:10px;display:block}

/* wide dialog: two columns */
.geo .dlg.wide .dlg-body, .geo .dlg.xwide .dlg-body{display:grid;grid-template-columns:1fr 1fr;gap:0 18px;align-content:start}
.geo .dlg.wide .dlg-body > .field:has(textarea), .geo .dlg.wide .dlg-body > .field:has(.coord-row), .geo .dlg.wide .dlg-body > :not(.field), .geo .dlg.xwide .dlg-body > :not(.field), .geo .dlg.xwide .dlg-body > .field:has(textarea){grid-column:1/-1}
/* ---------- attribute table dock ---------- */
.geo #attr-dock{position:absolute;left:var(--rail);right:0;bottom:26px;height:300px;min-height:120px;background:var(--glass);backdrop-filter:blur(14px);border-top:1px solid var(--line2);z-index:17;display:flex;flex-direction:column}
.geo #attr-dock.hidden{display:none}
.geo .dock-resize{height:5px;cursor:ns-resize;background:transparent}
.geo .dock-resize:hover{background:rgba(0,111,55,.28)}
.geo .dock-head{display:flex;align-items:center;gap:8px;padding:4px 10px 6px}
.geo .dock-head select{width:220px}
.geo .dock-head input{width:170px}
.geo .dock-tools{margin-left:auto;display:flex;gap:6px;align-items:center;flex-wrap:wrap;justify-content:flex-end}
.geo .dock-body{flex:1;overflow:auto}
.geo #attr-table{border-collapse:collapse;font-size:12px;min-width:100%;font-variant-numeric:tabular-nums}
.geo #attr-table th{position:sticky;top:0;background:var(--lembut);text-align:left;padding:6px 10px;border-bottom:1px solid var(--line2);border-right:1px solid var(--line);cursor:pointer;white-space:nowrap;user-select:none}
.geo #attr-table th .sort{color:var(--acc);margin-left:4px;font-size:10px}
.geo #attr-table td{padding:4px 10px;border-bottom:1px solid var(--line);border-right:1px solid var(--line);white-space:nowrap;max-width:280px;overflow:hidden;text-overflow:ellipsis}
.geo #attr-table tr:hover td{background:rgba(11,33,23,.03)}
.geo #attr-table tr.sel td{background:rgba(0,111,55,.11)}
.geo #attr-table td.num{text-align:right}
.geo #attr-table td[contenteditable]{outline:1px solid var(--acc);background:var(--permukaan)}
.geo .pager{display:flex;gap:6px;align-items:center;justify-content:center;padding:6px;color:var(--muted);font-size:11.5px}

/* ---------- toast ---------- */
.geo #toasts{position:absolute;right:14px;top:14px;z-index:60;display:flex;flex-direction:column;gap:8px;max-width:360px}
.geo .toast{background:var(--glass2);border:1px solid var(--line2);border-left:3px solid var(--acc);border-radius:10px;padding:10px 14px;box-shadow:var(--sh);font-size:12.5px;animation:pop .16s ease}
.geo .toast.ok{border-left-color:var(--ok)}.geo .toast.warn{border-left-color:var(--warn)}.geo .toast.err{border-left-color:var(--err)}
.geo .toast .t-title{font-weight:600;margin-bottom:2px}

/* ---------- context menu ---------- */
.geo #ctxmenu{position:absolute;z-index:50;background:var(--glass2);border:1px solid var(--line2);border-radius:10px;box-shadow:var(--sh);padding:5px;min-width:220px}
.geo #ctxmenu button{display:flex;width:100%;text-align:left;background:transparent;border:0;color:var(--fg);padding:7px 10px;border-radius:7px;gap:10px;align-items:center;font-size:12.5px}
.geo #ctxmenu button:hover{background:rgba(0,111,55,.1)}
.geo #ctxmenu .sep{height:1px;background:var(--line);margin:4px 2px}
.geo #ctxmenu .coord{padding:6px 10px 8px;color:var(--muted);font-size:11px;font-variant-numeric:tabular-nums;white-space:pre-line;line-height:1.5}

/* ---------- splash ---------- */
.geo #splash{position:absolute;inset:0;background:radial-gradient(1200px 700px at 30% 20%,#E4F1EA 0%,#F1F5F2 55%,#FFFFFF 100%);z-index:100;display:flex;align-items:center;justify-content:center;transition:opacity .4s ease}
.geo #splash.out{opacity:0;pointer-events:none}
.geo .splash-card{text-align:center;width:340px}
.geo .splash-logo{width:74px;height:74px;margin:0 auto 14px;border-radius:50%;border:2px solid var(--acc);position:relative;box-shadow:0 0 40px rgba(0,111,55,.3)}
.geo .splash-logo::before, .geo .splash-logo::after{content:"";position:absolute;inset:8px;border-radius:50%;border:1px solid rgba(0,111,55,.45)}
.geo .splash-logo::after{inset:22px}
.geo .splash-card h1{margin:0 0 4px;font-size:26px;font-weight:600;letter-spacing:.5px}
.geo .splash-card p{margin:0 0 16px;color:var(--fg2)}
.geo .splash-card .bar{height:5px;background:rgba(11,33,23,.06);border-radius:4px;overflow:hidden}
.geo .splash-card .bar div{height:100%;width:5%;background:var(--acc);transition:width .2s}
.geo .splash-card small{display:block;margin-top:8px;color:var(--muted);font-size:11px;min-height:14px}

/* ---------- misc ---------- */
.geo .hr{height:1px;background:var(--line);margin:12px 0}
.geo .badge{display:inline-flex;align-items:center;gap:6px;background:rgba(11,33,23,.04);border:1px solid var(--line);border-radius:20px;padding:3px 10px;font-size:11.5px;color:var(--fg2)}
.geo .class-row{display:grid;grid-template-columns:38px 1fr 1fr;gap:6px;align-items:center;margin-bottom:5px}
.geo .class-row input[type=text]{padding:5px 8px;font-size:12px}
.geo .mono{font-family:ui-monospace,Consolas,monospace}
.geo .flash{animation:flash .9s ease 3}
@keyframes flash{0%,100%{opacity:1}50%{opacity:.2}}
.geo kbd{background:rgba(11,33,23,.06);border-radius:4px;padding:0 5px;font-size:11px;border:1px solid var(--line2)}
.geo .progress{height:4px;background:rgba(11,33,23,.05);border-radius:3px;overflow:hidden;margin:6px 0}
.geo .progress div{height:100%;background:var(--acc);width:0;transition:width .15s}
@media (max-width:760px){.geo{--panel:min(320px,calc(100vw - 60px))}.geo #searchbox{width:calc(100vw - 80px)}.geo #legend{display:none}.geo .tool-grid{grid-template-columns:1fr}}

.geo .maplibregl-popup-content > div > .row:first-child{padding-right:18px}



/* =====================================================================
   Penyesuaian SI-BERSINAR — ditambahkan di akhir oleh alat/bangun-geo-css.py
   ===================================================================== */

/* Konstrix Geo aslinya satu halaman penuh: #app mengisi 100vw x 100vh.
   Di sini ia menumpang di dalam <main id="isi"> milik SI-BERSINAR, yang
   sudah dipersempit oleh sisi kiri dan kop. Jadi ukurannya mengikuti
   wadahnya, bukan jendela. */
#geo-app {
  position: absolute; inset: 0;
  width: auto; height: auto; margin: 0;
  overflow: hidden;
}

/* Rel kiri Geo dimatikan: menunya sudah pindah ke sisi kiri SI-BERSINAR
   sebagai submenu PETA. Dua rel bersebelahan berarti dua tempat berbeda
   untuk hal yang sama, dan 60 piksel yang terbuang. --rail dipakai juga
   oleh #panel, #legend, #statusbar dan kontrol MapLibre untuk menghitung
   jaraknya dari kiri, jadi cukup dinolkan di satu tempat. */
#geo-app { --rail: 0px; }
#geo-app #rail { display: none; }

/* Kotak cari Geo dimatikan dengan alasan yang sama: SI-BERSINAR sudah
   punya kotak cari di pojok kanan atas kop. Panel "Cari & Navigasi"
   milik Geo tetap ada dan tetap bisa dipakai lewat submenu. */
#geo-app #searchbox { display: none; }

/* Splash "Memuat data Kalimantan Tengah…" milik Geo menunggu
   KG_EMBEDDED, yang di sini sengaja kosong — lapisannya datang dari
   Supabase. Tanpa ini layarnya tertutup selamanya. */
#geo-app #splash { display: none; }

/* Bar status duduk di dasar wadah, bukan di dasar jendela. */
#geo-app #statusbar { padding-left: 12px; }

/* --- keterbacaan di atas latar terang ------------------------------
   Panel, dialog dan legenda Geo mengambang di atas citra satelit. Pada
   tema gelap mereka menonjol karena lebih gelap dari peta; pada tema
   terang bedanya tipis, jadi tepinya dipertegas dan bayangannya
   diperdalam sedikit — bukan dengan menggelapkan kembali isinya. */
#geo-app #panel,
#geo-app #legend,
#geo-app #attr-dock,
#geo-app .ctl,
#geo-app .ctl-group { border-color: var(--garis-kuat); }

#geo-app #panel { box-shadow: 6px 0 24px rgba(11, 33, 23, .10); }
#geo-app #legend { box-shadow: var(--bayang-md); }

/* Judul panel memakai warna lembaga, sejajar dengan kop SI-BERSINAR. */
#geo-app .panel-head h2 { color: var(--utama); letter-spacing: .01em; }

/* Tombol bundar di kanan bawah: pada peta terang, lingkaran putih nyaris
   hilang di atas awan atau jalan beton. Diberi latar penuh, bukan kaca. */
#geo-app .ctl,
#geo-app .ctl-group { background: var(--permukaan); }
#geo-app .ctl:hover { background: var(--utama-isi); color: var(--utama); }
#geo-app .ctl.on { background: var(--utama); border-color: var(--utama); color: #fff; }

/* Bilah skala dan atribusi MapLibre duduk di atas peta, bukan di atas
   panel — keduanya butuh latar sendiri agar terbaca di citra terang. */
#geo-app .maplibregl-ctrl-scale { font-weight: 600; }

/* --- layar penuh ----------------------------------------------------
   Saat #geo-app dinaikkan ke layar penuh ia keluar dari <main id="isi">
   dan tidak lagi punya induk berposisi, jadi `position:absolute;inset:0`
   di atas tidak lagi berarti "seukuran wadah". Ukurannya dipatok
   langsung ke layar. Latar belakang wajib ditulis: elemen layar penuh
   digambar di atas lapisan teratas, tanpa mewarisi latar apa pun. */
#geo-app:fullscreen {
  position: fixed; inset: 0;
  width: 100vw; height: 100vh;
  background: var(--kanvas);
}
/* Tombol layar penuh menyala saat aktif, seperti tombol globe. */
#geo-app #ctl-full.on { background: var(--utama); border-color: var(--utama); color: #fff; }

/* --- bilah skala tidak boleh tertutup panel -------------------------
   Kontrol kiri-bawah MapLibre berada DI DALAM #map, yang letaknya
   sebelum #panel di pohon dokumen — jadi tidak ada pemilih saudara yang
   bisa menggesernya saat panel terbuka. :has() pada wadahnya bisa:
   ia menanyakan keadaan anak, bukan urutan. Peramban yang tidak
   mengenal :has() mengabaikan seluruh aturan ini dan bilah skalanya
   tetap di tempat semula — tertutup panel, tetapi tidak rusak. */
#geo-app:has(#panel:not(.hidden)) .maplibregl-ctrl-bottom-left {
  left: calc(var(--rail) + var(--panel));
  transition: left .18s ease;
}

/* --- pemilih wilayah administratif ----------------------------------
   Empat baris bertingkat: Provinsi, Kabupaten/Kota, Kecamatan, Desa.
   Label di kiri dengan lebar tetap supaya keempat kotak pilihannya
   berbaris pada tepi yang sama — kalau labelnya mengikuti panjang
   teksnya sendiri, kotaknya bertangga dan tingkatannya jadi sulit
   dibaca sekilas. */
.geo .wil-kotak { display: flex; flex-direction: column; gap: 6px }
.geo .wil-baris { display: flex; align-items: center; gap: 8px }
.geo .wil-label {
  flex: 0 0 118px; font-size: 11.5px; font-weight: 600;
  color: var(--fg2); line-height: 1.2;
}
.geo .wil-baris select { flex: 1; min-width: 0 }

/* Satu baris kabar untuk tiga keadaan: sedang mengambil, berhasil
   (dengan luasnya, supaya besarnya permintaan terlihat SEBELUM tombol
   Muat ditekan), dan gagal. */
.geo .wil-kabar {
  margin-top: 7px; font-size: 11.5px; line-height: 1.4;
  color: var(--muted); min-height: 16px;
}
.geo .wil-kabar.baik { color: var(--ok); font-weight: 600 }
.geo .wil-kabar.buruk { color: var(--err) }

/* Dialog lebar disusun dua kolom. Pemilih wilayah berisi empat baris
   bertingkat — di setengah lebar, nama kecamatan dan desa terpotong,
   dan kolom sebelahnya menganga kosong setinggi blok ini. Jadi ia
   melebar penuh, seperti perlakuan yang sudah berlaku untuk textarea. */
.geo .dlg.wide .dlg-body > .wil-field,
.geo .dlg.xwide .dlg-body > .wil-field { grid-column: 1 / -1 }
.geo .wil-baris select { max-width: 420px }

/* Ringkasan ukuran berjalan di bilah petunjuk gambar. Diberi latar
   sendiri supaya angkanya terbaca sebagai nilai, bukan sebagai
   lanjutan kalimat petunjuk di sebelahnya. */
.geo .pick-hint .pick-ukur:not(:empty) {
  background: rgba(255, 255, 255, .22);
  border-radius: 20px; padding: 3px 11px;
  font-variant-numeric: tabular-nums; font-weight: 700;
  white-space: nowrap;
}

/* --- bilah petunjuk gambar/ukur --------------------------------------
   Aslinya satu baris pendek. Sekarang ia juga memikul ringkasan ukuran
   berjalan, dan wadahnya menyempit karena panel alat terbuka di kiri —
   hasilnya kalimat petunjuk terperas menjadi satu kata per baris dan
   bilahnya menjulur setinggi 225 piksel menutupi peta. Tiga hal yang
   memperbaikinya: lebarnya dibatasi, isinya boleh turun baris sebagai
   kelompok utuh, dan kalimat petunjuknya diberi hak melar sementara
   tombol-tombolnya tidak boleh menyusut. */
.geo .pick-hint {
  flex-wrap: wrap;
  max-width: min(720px, calc(100% - 28px));
  row-gap: 8px;
}
.geo .pick-hint > span:first-child {
  flex: 1 1 240px; min-width: 180px;
  white-space: normal; font-weight: 600;
}
.geo .pick-hint .pick-ukur,
.geo .pick-hint button { flex: 0 0 auto }

/* Saat panel alat terbuka, bilahnya digeser ke kanan supaya tidak
   menumpuk di atas panel — sama seperti perlakuan legenda. */
#geo-app:has(#panel:not(.hidden)) .pick-hint {
  left: calc(var(--rail) + var(--panel) + (100% - var(--rail) - var(--panel)) / 2);
  max-width: min(720px, calc(100% - var(--rail) - var(--panel) - 28px));
}

/* =====================================================================
   ALAT UKUR DI PANEL KIRI
   Bentuknya mengikuti Ruler Google Earth — tab di atas, angka di
   tengah, tombol di bawah — tetapi tabnya ikon dan tombolnya ikon,
   sehingga muat di lebar panel tanpa satu pun kata terpotong. Ia satu
   blok berbingkai supaya terbaca sebagai alat, bukan sebagai daftar
   pengaturan yang menempel di atas daftar alat lain.
   ===================================================================== */
.geo .ukur-blok {
  border: 1px solid var(--garis-kuat);
  border-radius: 12px;
  background: var(--permukaan);
  overflow: hidden;
  margin-bottom: 4px;
  user-select: none;
}

/* --- tab ikon --- */
.geo .ukur-tab { display: flex; gap: 2px; padding: 6px; border-bottom: 1px solid var(--garis) }
.geo .ukur-tab button {
  flex: 1; height: 34px; border: 0; border-radius: 7px;
  background: none; color: var(--teks-3); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.geo .ukur-tab button svg {
  width: 19px; height: 19px; fill: none; stroke: currentColor;
  stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
}
.geo .ukur-tab button:hover { background: var(--lembut); color: var(--teks) }
.geo .ukur-tab button.on { background: var(--utama-isi); color: var(--utama) }

/* Baris keterangan menggantikan nama tab yang sudah tidak tertulis:
   ikon cepat dikenali, tetapi hanya kalimat ini yang memastikan
   tebakannya benar. */
.geo .ukur-ket {
  padding: 8px 12px 0; font-size: 11px; line-height: 1.4;
  color: var(--teks-3);
}

/* --- angka --- */
.geo .ukur-isi { padding: 8px 12px 10px }
.geo .ukur-baris {
  display: flex; align-items: center; gap: 6px;
  padding: 4px 0; min-height: 26px;
}
.geo .ukur-label { flex: 0 0 74px; color: var(--teks-3); font-size: 11px; line-height: 1.2; white-space: nowrap }
.geo .ukur-nilai {
  flex: 1; text-align: right; font-weight: 700; color: var(--teks);
  font-variant-numeric: tabular-nums; white-space: nowrap; font-size: 13px;
}
.geo .ukur-sat {
  flex: 0 0 58px; height: 24px; padding: 0 4px; font-size: 11px; text-align: center;
  border: 1px solid var(--garis); border-radius: 6px;
  background: var(--permukaan); color: var(--teks-2);
}
.geo .ukur-sat.kosong { border: 0; background: none; pointer-events: none }

/* --- tombol aksi: ikon semua, tanpa satu pun kata --- */
.geo .ukur-kaki {
  display: flex; gap: 6px; padding: 8px 10px;
  border-top: 1px solid var(--garis); background: var(--lembut);
}
.geo .ukur-aksi {
  flex: 1; height: 32px; border-radius: 8px; cursor: pointer;
  border: 1px solid var(--garis); background: var(--permukaan);
  color: var(--teks-2);
  display: flex; align-items: center; justify-content: center;
}
.geo .ukur-aksi svg {
  width: 16px; height: 16px; fill: none; stroke: currentColor;
  stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round;
}
.geo .ukur-aksi:hover:not(:disabled) { background: var(--utama-isi); color: var(--utama); border-color: var(--utama-garis) }
.geo .ukur-aksi:disabled { opacity: .38; cursor: default }
.geo .ukur-aksi.utama { background: var(--utama); border-color: var(--utama); color: #fff }
.geo .ukur-aksi.utama:hover:not(:disabled) { background: var(--utama-sentuh); color: #fff }
.geo .ukur-aksi.utama:disabled { background: var(--permukaan); border-color: var(--garis); color: var(--teks-2) }

/* =====================================================================
   DUA BILAH: LAYER DI KIRI, ALAT DI KANAN
   ---------------------------------------------------------------------
   Layer bukan alat yang sesekali dibuka lalu ditutup — ia daftar yang
   ingin dilihat terus-menerus sambil mengerjakan hal lain. Karena itu
   ia menetap di sisi kiri. Panel alat, yang memang berganti-ganti
   isinya mengikuti alat yang dipilih, pindah ke tepi kanan peta.
   ===================================================================== */
#geo-app #panel {
  left: auto; right: 0;
  border-right: 0; border-left: 1px solid var(--line);
  box-shadow: -6px 0 24px rgba(11, 33, 23, .10);
}
#geo-app #panel.hidden { transform: translateX(16px) }

/* Legenda dan bilah skala duduk di kiri bawah; panel tidak lagi di
   kiri, jadi keduanya tidak perlu bergeser lagi. */
#geo-app #legend.shifted { left: calc(var(--rail) + 14px) }
#geo-app:has(#panel:not(.hidden)) .maplibregl-ctrl-bottom-left { left: var(--rail) }

/* Yang justru harus menyingkir sekarang adalah kontrol dan atribusi di
   kanan bawah. */
#geo-app:has(#panel:not(.hidden)) #map-controls { right: calc(var(--panel) + 12px) }
#geo-app:has(#panel:not(.hidden)) .maplibregl-ctrl-bottom-right { right: var(--panel) }
#geo-app #map-controls,
#geo-app .maplibregl-ctrl-bottom-right { transition: right .18s ease }

/* Tabel atribut membentang dari tepi kiri sampai tepi panel. */
#geo-app #attr-dock { left: 0 }
#geo-app:has(#panel:not(.hidden)) #attr-dock { right: var(--panel) }

/* --- blok "sedang menggambar" di puncak bilah kanan ----------------- */
#geo-app #panel-sketsa {
  flex: 0 0 auto;
  padding: 10px 14px 12px;
  background: var(--utama-isi);
  border-bottom: 1px solid var(--utama-garis);
}
#geo-app #panel-sketsa[hidden] { display: none }
.geo .sketsa-teks {
  font-size: 12px; line-height: 1.45; color: var(--utama-gelap);
  display: flex; flex-direction: column; gap: 5px;
}
.geo .sketsa-teks .pick-ukur:not(:empty) {
  align-self: flex-start;
  background: var(--utama); color: #fff;
  border-radius: 20px; padding: 3px 11px;
  font-variant-numeric: tabular-nums; font-weight: 700; font-size: 11.5px;
  white-space: nowrap;
}
.geo .sketsa-tbl { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 9px }

/* --- daftar layer di sisi kiri SI-BERSINAR --------------------------
   Wadahnya membawa kelas .geo supaya isinya bergaya seperti di dalam
   peta. Kelas itu juga membawa aturan turunan html/body milik Geo —
   tinggi penuh, latar sendiri, overflow terkunci — yang di sini justru
   salah; ketiganya dikembalikan ke perilaku biasa. */
#sisi-layer { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column }
#sisi-layer:empty { display: none }
/* Pemilihnya sengaja diawali #sisi. Aturan `.geo:not(#geo-app)` di kaki
   berkas ini memaksa `overflow: visible` pada setiap pembungkus .geo di
   luar peta, dan `:not(#geo-app)` membawa bobot ID — tanpa #sisi di
   depan, `overflow: visible` itu MENGALAHKAN `overflow-y: auto` di sini
   dan daftar layer berhenti bisa digulung: isinya terpotong begitu saja
   di tepi bawah, padahal masih ada layer di bawahnya. */
#sisi .sisi-layer-isi.geo {
  position: static; height: auto; width: auto; margin: 0;
  overflow-y: auto; overflow-x: hidden; flex: 1 1 auto; min-height: 0;
  background: none;
  scrollbar-width: thin;
  overscroll-behavior: contain;
}
#sisi .sisi-layer-isi.geo::-webkit-scrollbar { width: 8px }
#sisi .sisi-layer-isi.geo::-webkit-scrollbar-thumb {
  background: var(--line2); border-radius: 4px;
  border: 2px solid transparent; background-clip: content-box;
}
#sisi .sisi-layer-isi.geo::-webkit-scrollbar-thumb:hover { background: var(--muted); background-clip: content-box }
.sisi-layer-isi.geo .lyr-toolbar { padding: 0 0 8px }
.sisi-layer-isi.geo .btn { font-size: 11.5px }

/* Tombol buang folder kosong, menempel di kanan judul folder. */
.geo .lyr-group-head { display: flex; align-items: center; gap: 6px }
.geo .lyr-group-head > span { flex: 1; min-width: 0 }
.geo .lyr-folder-x { flex: 0 0 auto; opacity: .55 }
.geo .lyr-folder-x:hover { opacity: 1; color: var(--err) }

/* --- baris judul daftar layer ---------------------------------------
   Ikon, tulisan, lalu tombol-tombol sebagai ikon di ujung kanan. Semua
   dalam satu baris: di sisi kiri yang hanya selebar 243 piksel, lima
   tombol bertuliskan kata memakan dua baris penuh sebelum satu layer
   pun sempat tampil. */
.geo .lyr-kepala {
  display: flex; align-items: center; gap: 6px;
  padding: 0 0 10px; border-bottom: 1px solid var(--line);
  margin-bottom: 10px;
}
.geo .lyr-kepala-ikon { flex: 0 0 auto; display: flex; color: var(--acc) }
.geo .lyr-kepala-ikon svg {
  width: 17px; height: 17px; fill: none; stroke: currentColor;
  stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
}
.geo .lyr-kepala-teks {
  /* Lima tombol memakan 120 piksel dari 243 yang ada; jarak hurufnya
     dikecilkan dan tulisannya diberi hak memotong dengan elipsis,
     supaya ia menyusut dengan rapi alih-alih meluber diam-diam. */
  flex: 1 1 auto; min-width: 0; font-size: 10.5px; font-weight: 800;
  letter-spacing: .05em; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.geo .lyr-kepala-tbls { flex: 0 0 auto; display: flex; gap: 0 }
.geo .lyr-kepala-tbl {
  width: 24px; height: 24px; border: 0; border-radius: 7px;
  background: none; color: var(--fg2); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.geo .lyr-kepala-tbl svg {
  width: 15px; height: 15px; fill: none; stroke: currentColor;
  stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
}
.geo .lyr-kepala-tbl:hover { background: var(--bg3); color: var(--acc) }

/* =====================================================================
   PANEL RUTE
   Dua baris titik bertanda A dan B, opsi, lalu kartu hasil — susunan
   yang sudah dikenal orang dari Google Maps.
   ===================================================================== */
.geo .rute-bungkus { position: relative; margin-bottom: 8px }
.geo .rute-baris { display: flex; align-items: center; gap: 8px }
.geo .rute-huruf {
  flex: 0 0 24px; height: 24px; border-radius: 50%;
  background: var(--acc); color: #fff;
  font-size: 12px; font-weight: 800;
  display: flex; align-items: center; justify-content: center;
}
.geo .rute-baris input { flex: 1; min-width: 0 }
.geo .rute-tbl {
  flex: 0 0 auto; width: 32px; height: 32px;
  border: 1px solid var(--line2); border-radius: 8px;
  background: var(--bg2); color: var(--fg2); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.geo .rute-tbl svg {
  width: 16px; height: 16px; fill: none; stroke: currentColor;
  stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
}
.geo .rute-tbl:hover { background: var(--bg3); color: var(--acc); border-color: var(--acc) }

.geo .rute-hasil {
  position: absolute; top: calc(100% + 4px); left: 32px; right: 40px; z-index: 30;
  max-height: 220px; overflow-y: auto; padding: 4px;
  background: var(--glass2); border: 1px solid var(--line2);
  border-radius: 10px; box-shadow: var(--sh);
}
.geo .rute-hasil[hidden] { display: none }
.geo .rute-pilihan {
  display: flex; flex-direction: column; gap: 1px;
  padding: 7px 9px; border-radius: 7px; cursor: pointer;
}
.geo .rute-pilihan:hover { background: var(--bg3) }
.geo .rute-pilihan b { font-size: 12.5px }
.geo .rute-pilihan span {
  font-size: 11px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.geo .rute-kosong { padding: 8px 9px; font-size: 12px; color: var(--muted) }

.geo .rute-aksi-baris { display: flex; gap: 6px; margin: 2px 0 6px }
.geo .rute-moda { display: flex; gap: 4px; margin-bottom: 10px }
.geo .rute-moda-tbl {
  flex: 1; height: 32px; border: 1px solid var(--line2); border-radius: 8px;
  background: var(--bg2); color: var(--fg2);
  font-size: 12px; font-weight: 600; cursor: pointer;
}
.geo .rute-moda-tbl:hover { background: var(--bg3); color: var(--fg) }
.geo .rute-moda-tbl.on { background: var(--acc); border-color: var(--acc); color: #fff }

.geo .rute-ringkas { display: flex; flex-direction: column; gap: 7px }
.geo .rute-kartu {
  display: flex; flex-direction: column; gap: 2px; text-align: left;
  padding: 10px 12px; border: 1px solid var(--line2); border-radius: 10px;
  background: var(--bg2); cursor: pointer; color: var(--fg);
}
.geo .rute-kartu:hover { border-color: var(--acc) }
.geo .rute-kartu.on { border-color: var(--acc); background: var(--utama-isi) }
.geo .rute-kartu b { font-size: 16px; font-weight: 800; color: var(--acc) }
.geo .rute-kartu span { font-size: 11.5px; color: var(--fg2) }
.geo .rute-kartu i { font-style: normal; font-size: 10.5px; color: var(--muted) }
.geo .rute-galat { font-size: 12px; line-height: 1.5; color: var(--err) }
.geo .btn.block { width: 100%; justify-content: center }

/* Catatan penyeberangan feri di hasil rute. */
.geo .rute-feri {
  display: flex; flex-direction: column; gap: 3px;
  padding: 9px 12px; border-radius: 10px;
  background: var(--awas-isi); border: 1px solid var(--awas);
}
.geo .rute-feri b { font-size: 12.5px; color: var(--awas) }
.geo .rute-feri span { font-size: 11.5px; color: var(--fg2) }
.geo .rute-feri i { font-style: normal; font-size: 10.5px; color: var(--muted) }

/* Tombol bawa-keluar: dua per baris, supaya keempatnya muat di panel
   selebar 360 px tanpa satu pun namanya terpotong. */
.geo .rute-ekspor { display: grid; grid-template-columns: 1fr 1fr; gap: 6px }
.geo .rute-ekspor .btn { width: 100%; justify-content: center }

/* Catatan jalur air. Warnanya sengaja BUKAN warna peringatan seperti
   feri: ini bukan hambatan pada perjalanan darat, melainkan jenis
   perjalanan yang lain. Birunya sama dengan garis putus-putus di peta,
   supaya keterangan di panel dan garis di peta terbaca sebagai satu
   hal yang sama. */
.geo .rute-air {
  display: flex; flex-direction: column; gap: 3px;
  padding: 9px 12px; border-radius: 10px;
  background: color-mix(in srgb, #0891b2 12%, transparent);
  border: 1px solid color-mix(in srgb, #0891b2 55%, transparent);
}
.geo .rute-air b { font-size: 12.5px; color: #0e7490 }
.geo .rute-air span { font-size: 11.5px; color: var(--fg2) }
.geo .rute-air i { font-style: normal; font-size: 10.5px; color: var(--muted); line-height: 1.45 }
:root[data-tema="gelap"] .geo .rute-air b { color: #5FC8DE }

/* --- ikon pada kartu alat -------------------------------------------
   Ikon di baris sendiri di atas judul, bukan di sebelahnya: nama alat
   di sini sering dua baris ("Spatial join / hitung titik"), dan ikon di
   sebelah kiri akan membuat kolom teksnya tinggal separuh lebar kartu. */
.geo .tool-card { position: relative }
.geo .tool-ico { display: block; color: var(--acc); margin-bottom: 6px }
.geo .tool-ico svg {
  width: 20px; height: 20px; fill: none; stroke: currentColor;
  stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
}
.geo .tool-card:hover .tool-ico { color: var(--acc2) }

/* --- rincian pengukuran ---------------------------------------------
   Isinya pindahan dari dua alat "Ukur (rincian)" yang dulu berdiri
   sendiri. Ditutup secara bawaan: yang dicari orang sembilan dari
   sepuluh kali adalah satu angka besar di atas, bukan tabelnya. */
.geo .ukur-rinci-tbl {
  width: 100%; margin-top: 6px; padding: 6px 8px;
  border: 1px dashed var(--line2); border-radius: 8px;
  background: none; color: var(--fg2); cursor: pointer;
  font-size: 11.5px; font-weight: 600; text-align: left;
}
.geo .ukur-rinci-tbl::before { content: '\25B8 '; }
.geo .ukur-rinci-tbl.on::before { content: '\25BE '; }
.geo .ukur-rinci-tbl:hover { color: var(--acc); border-color: var(--acc) }
.geo .ukur-rinci { margin-top: 6px }
.geo .ukur-rinci-baris {
  display: flex; justify-content: space-between; gap: 8px;
  padding: 3px 0; font-size: 11px;
}
.geo .ukur-rinci-baris span { color: var(--muted) }
.geo .ukur-rinci-baris b { font-variant-numeric: tabular-nums; font-size: 11px }
.geo .ukur-tabel { width: 100%; border-collapse: collapse; margin-top: 6px; font-size: 11px }
.geo .ukur-tabel th {
  text-align: left; font-weight: 700; color: var(--muted);
  border-bottom: 1px solid var(--line); padding: 3px 4px;
}
.geo .ukur-tabel td { padding: 3px 4px; border-bottom: 1px solid var(--line); font-variant-numeric: tabular-nums }

/* Pilihan tema & kotak akun di panel Pengaturan. */
.geo .atur-blok { margin-bottom: 4px }
.geo .tema-pilih { display: flex; gap: 6px }
.geo .tema-tbl {
  flex: 1; height: 34px; border: 1px solid var(--line2); border-radius: 9px;
  background: var(--bg2); color: var(--fg2);
  font-size: 12.5px; font-weight: 600; cursor: pointer;
}
.geo .tema-tbl:hover { background: var(--bg3); color: var(--fg) }
.geo .tema-tbl.on { background: var(--acc); border-color: var(--acc); color: #fff }
.geo .akun { display: flex; align-items: center; gap: 10px; padding: 6px 0 10px }
.geo .akun-bulat {
  width: 34px; height: 34px; border-radius: 50%; flex-shrink: 0;
  background: var(--utama-isi); color: var(--acc);
  font-size: 12px; font-weight: 700; display: flex; align-items: center; justify-content: center;
}
.geo .akun-teks { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1 }
.geo .akun-teks b { font-size: 13px }
.geo .akun-teks i { font-style: normal; font-size: 11px; color: var(--muted) }

/* Kotak cari mesin peta dipindah ke kop: posisinya tidak lagi
   mengambang di atas peta, melainkan mengikuti aliran pita. */
.kop-cari { flex: 0 0 auto }
.kop-cari #searchbox {
  display: flex; position: relative;
  left: auto; top: auto; right: auto;
  width: min(360px, 34vw); max-width: none; height: 40px;
  border-radius: 10px; box-shadow: none;
  background: var(--lembut); border: 1px solid var(--garis);
  backdrop-filter: none; z-index: auto;
}
.kop-cari #search-results {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0;
  max-height: 60vh; overflow-y: auto; z-index: 60;
  background: var(--permukaan); border: 1px solid var(--garis);
  border-radius: var(--r-md); box-shadow: var(--bayang-md); padding: 4px;
}

/* =====================================================================
   Pembungkus .geo DI LUAR peta
   ---------------------------------------------------------------------
   Potongan antarmuka Geo kini hidup di dua tempat: di dalam peta
   (#geo-app) dan di dalam kerangka SI-BERSINAR — daftar layer di sisi
   kiri, kotak cari di kop. Supaya gayanya ikut, pembungkusnya diberi
   kelas .geo, dan itulah masalahnya: alat lingkup-css mengubah aturan
   `html`, `body` dan `#app` milik Geo menjadi aturan `.geo` juga. Jadi
   setiap pembungkus kecil ikut mewarisi `width:100vw; height:100vh;
   overflow:hidden` — kotak cari selebar 360 px membentang menutupi
   seluruh layar dan menelan klik pada deretan alat di sebelahnya.

   Aturan itu memang milik AKAR aplikasi peta, bukan milik kelasnya.
   Di sini ia dikembalikan ke tempatnya: hanya #geo-app yang jadi
   sebesar jendela; pembungkus lain sebesar isinya sendiri.
   ===================================================================== */
.geo:not(#geo-app) {
  position: relative;
  width: auto; height: auto;
  overflow: visible;
  background: transparent;
  margin: 0;
}

/* =====================================================================
   PANEL ALAT DI LAYAR SEMPIT
   ---------------------------------------------------------------------
   Di layar lebar, panel alat duduk 360 piksel di tepi kanan peta. Di
   ponsel 320 piksel dari 412 berarti peta tinggal 92 piksel — panelnya
   bekerja, tetapi peta yang sedang dikerjakannya tidak lagi terlihat.

   Di sini ia menjadi lembar bawah: melebar penuh, setinggi 62% layar,
   dengan peta tetap tampak di atasnya. Itu juga posisi yang paling
   mudah dijangkau ibu jari.
   ===================================================================== */
@media (max-width: 900px) {
  .geo #panel, .geo #panel-sketsa {
    left: 0 !important; right: 0 !important; width: auto !important;
    top: auto !important; bottom: 0 !important; height: 62vh;
    border-right: 0; border-left: 0;
    border-top: 1px solid var(--line);
    border-radius: 16px 16px 0 0;
    box-shadow: 0 -10px 30px rgba(0,0,0,.28);
  }
  /* Kendali peta dan atribusi tidak lagi digeser ke samping: yang
     menutupi peta sekarang ada di bawah, bukan di sebelah kanan. */
  .geo.panel-buka #map-controls { right: 10px }
  .geo #legend { display: none }
  .geo .tool-grid { grid-template-columns: 1fr 1fr }
  .geo .dialog { width: calc(100vw - 24px); max-width: none }
}

/* Bilah status di layar sempit: yang berguna di lapangan adalah
   koordinat dan skala. Nama penyelenggara sudah tertulis di kop dan di
   sini hanya terpotong jadi "SI-…", yang tidak memberi tahu apa pun. */
@media (max-width: 900px) {
  .geo #st-brand, .geo #st-zoom, .geo #st-msg { display: none }
  .geo #statusbar { gap: 10px; font-size: 10.5px }
}

/* --- rute banyak tujuan ---------------------------------------------- */
.geo .rute-huruf.awal { background: var(--acc); color: var(--utama-isi-teks) }
.geo .rute-buang { color: var(--muted) }
.geo .rute-buang:hover { color: var(--err) }

.geo .rute-saklar { display: grid; gap: 8px; margin: 10px 0 4px }
.geo .rute-centang { display: flex; gap: 8px; align-items: flex-start; cursor: pointer }
.geo .rute-centang input { margin-top: 2px; flex: 0 0 auto }
.geo .rute-centang span { display: flex; flex-direction: column; gap: 1px; min-width: 0 }
.geo .rute-centang b { font-size: 12.5px; color: var(--fg) }
.geo .rute-centang i { font-style: normal; font-size: 10.5px; color: var(--muted); line-height: 1.4 }

.geo .rute-disusun {
  display: flex; flex-direction: column; gap: 2px;
  padding: 8px 11px; border-radius: 10px; margin-top: 8px;
  background: var(--ok-isi); border: 1px solid var(--ok);
}
.geo .rute-disusun b { font-size: 12px; color: var(--ok) }
.geo .rute-disusun span { font-size: 10.5px; color: var(--muted); line-height: 1.45 }

.geo .rute-etape { display: flex; flex-direction: column; gap: 2px }
.geo .rute-etape-baris {
  display: flex; align-items: center; gap: 9px;
  padding: 7px 9px; border-radius: 9px; background: var(--bg2);
}
.geo .rute-etape-no {
  flex: 0 0 auto; width: 20px; height: 20px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--acc); color: var(--utama-isi-teks);
  font-size: 10.5px; font-weight: 700;
}
.geo .rute-etape-teks { display: flex; flex-direction: column; gap: 1px; min-width: 0 }
.geo .rute-etape-teks b { font-size: 12px; color: var(--fg); overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.geo .rute-etape-teks span { font-size: 10.5px; color: var(--muted) }

/* Catatan ruas jalan kaki. Jingga, sewarna garis titik-titik di peta. */
.geo .rute-kaki {
  display: flex; flex-direction: column; gap: 3px;
  padding: 9px 12px; border-radius: 10px;
  background: color-mix(in srgb, #C2410C 11%, transparent);
  border: 1px solid color-mix(in srgb, #C2410C 50%, transparent);
}
.geo .rute-kaki b { font-size: 12.5px; color: #9A3412 }
.geo .rute-kaki span { font-size: 11.5px; color: var(--fg2) }
.geo .rute-kaki i { font-style: normal; font-size: 10.5px; color: var(--muted); line-height: 1.45 }
:root[data-tema="gelap"] .geo .rute-kaki b { color: #F0A87E }

/* Peringatan bahwa ruas terakhir belum terpetakan. */
.geo .rute-jauh {
  display: flex; flex-direction: column; gap: 3px;
  padding: 9px 12px; border-radius: 10px;
  background: var(--awas-isi); border: 1px solid var(--awas);
}
.geo .rute-jauh b { font-size: 12.5px; color: var(--awas) }
.geo .rute-jauh span { font-size: 11.5px; color: var(--fg2) }
.geo .rute-jauh i { font-style: normal; font-size: 10.5px; color: var(--muted); line-height: 1.45 }

/* --- petunjuk perjalanan --------------------------------------------- */
.geo .rute-legenda { display: flex; flex-wrap: wrap; gap: 4px 12px; margin: 2px 0 8px }
.geo .rute-leg { display: inline-flex; align-items: center; gap: 6px }
.geo .rute-leg i { width: 18px; height: 0; border-top-width: 3px; border-top-style: solid; border-radius: 2px }
.geo .rute-leg b { font-size: 10.5px; font-weight: 600; color: var(--muted) }
.geo .rute-leg-darat i { border-top-color: #1d4ed8 }
.geo .rute-leg-feri  i { border-top-color: #38bdf8 }
.geo .rute-leg-air   i { border-top-color: #0891b2; border-top-style: dashed }
.geo .rute-leg-kaki  i { border-top-color: #C2410C; border-top-style: dotted }

.geo ol.rute-langkah { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column }
.geo ol.rute-langkah li {
  position: relative; padding: 6px 0 6px 22px;
  font-size: 12px; line-height: 1.45; color: var(--fg2);
  display: flex; flex-direction: column; gap: 2px;
}
/* Garis tegak yang menyambung langkah satu ke langkah berikutnya —
   bentuk yang sudah dikenal orang dari jadwal perjalanan. */
.geo ol.rute-langkah li::before {
  content: ''; position: absolute; left: 5px; top: 0; bottom: 0;
  border-left: 2px solid var(--line2);
}
.geo ol.rute-langkah li:first-child::before { top: 12px }
.geo ol.rute-langkah li:last-child::before { bottom: calc(100% - 12px) }
.geo ol.rute-langkah li::after {
  content: ''; position: absolute; left: 1px; top: 8px;
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--bg2); border: 2px solid var(--line2);
}
.geo ol.rute-langkah li.rute-langkah-mulai::after,
.geo ol.rute-langkah li.rute-langkah-tiba::after { background: var(--acc); border-color: var(--acc) }
.geo ol.rute-langkah li.rute-langkah-singgah::after { background: var(--acc); border-color: var(--acc) }
.geo ol.rute-langkah li.mode-air::after { border-color: #0891b2 }
.geo ol.rute-langkah li.mode-kaki::after { border-color: #C2410C }
.geo ol.rute-langkah li.rute-langkah-mulai,
.geo ol.rute-langkah li.rute-langkah-tiba,
.geo ol.rute-langkah li.rute-langkah-singgah { font-weight: 700; color: var(--fg) }
.geo ol.rute-langkah li.rute-langkah-ganti { color: var(--fg); font-weight: 600 }
.geo .rute-langkah-ke {
  align-self: flex-start; border: 0; background: none; padding: 0;
  font: inherit; font-size: 10.5px; font-weight: 400; color: var(--muted);
  cursor: pointer; text-decoration: underline dotted;
}
.geo .rute-langkah-ke:hover { color: var(--acc) }

/* --- layer dinas sebagai jaringan rute -------------------------------- */
.geo .rute-layer { display: flex; flex-direction: column; gap: 4px }
.geo .rute-layer-baris { display: flex; align-items: center; gap: 8px }
.geo .rute-layer-nama {
  flex: 1 1 auto; min-width: 0; font-size: 12px; color: var(--fg2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.geo .rute-layer-sel {
  flex: 0 0 auto; max-width: 52%; height: 28px; font-size: 11.5px;
  border: 1px solid var(--line); border-radius: 8px;
  background: var(--bg2); color: var(--fg); padding: 0 6px;
}

/* Kartu hasil selagi masih dihitung: angka garis lurus dulu, supaya ada
   yang bisa dibaca sejak detik pertama. */
.geo .rute-kartu.sibuk { border-style: dashed; opacity: .9 }
.geo .rute-kartu.sibuk b { color: var(--muted) }
