:root{--bg:#f4f6f9;--card:#fff;--ink:#1d2433;--mut:#6b7587;--line:#e2e6ee;--pri:#2f5de0;--pri-d:#2347b5;--ok:#1f8a4c;--bad:#c93a3a;--warn:#b7791f;--r:8px}
*{box-sizing:border-box}
body{margin:0;font:15px/1.5 system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;color:var(--ink);background:var(--bg)}
a{color:var(--pri)}
h1{font-size:1.5rem;margin:.2em 0 .6em}h2{font-size:1.25rem;margin:.2em 0 .5em}h3{font-size:1.05rem;margin:.2em 0 .5em}
code{background:#eef1f7;padding:1px 5px;border-radius:4px;font-size:.9em}
.topbar{display:flex;align-items:center;gap:12px;background:#fff;border-bottom:1px solid var(--line);padding:10px 20px}
.brand{font-weight:700;font-size:1.1rem;text-decoration:none;color:var(--ink)}.brand span{color:var(--pri)}
.main{max-width:1100px;margin:20px auto;padding:0 16px}
body.builder .main{max-width:1500px}
.foot{text-align:center;color:var(--mut);font-size:.8rem;padding:20px}
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--r);padding:16px;margin-bottom:16px}
.card.narrow,.narrow{max-width:520px;margin-left:auto;margin-right:auto}
.center{text-align:center}.muted{color:var(--mut)}
.badge{display:inline-block;background:#eef1f7;color:var(--mut);border-radius:10px;padding:0 8px;font-size:.75rem}
.badge.ok{background:#e1f4e9;color:var(--ok)}.badge.bad{background:#fbe3e3;color:var(--bad)}
.flash{padding:10px 20px;margin:0;border-bottom:1px solid var(--line);background:#e1f4e9;color:var(--ok)}
.card .flash{margin:0 0 12px;border:1px solid;border-radius:6px}
.flash.err{background:#fbe3e3;color:var(--bad)}
.btn{display:inline-block;border:1px solid var(--line);background:#fff;color:var(--ink);padding:7px 14px;border-radius:6px;cursor:pointer;font:inherit;text-decoration:none}
.btn:hover{border-color:var(--pri)}
.btn.primary{background:var(--pri);border-color:var(--pri);color:#fff}.btn.primary:hover{background:var(--pri-d)}
.btn.danger{color:var(--bad)}.btn.sso{background:#111827;color:#fff;border-color:#111827;text-align:center}
.btn.sm{padding:3px 9px;font-size:.85rem}.btn.block{display:block;width:100%;text-align:center}
.btn.on{background:#eaf0ff;border-color:var(--pri);color:var(--pri-d)}
.inline{display:inline}
.row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.row.between{justify-content:space-between}.row.end{justify-content:flex-end}
.field{margin-bottom:12px}.field label{display:block;font-weight:600;margin-bottom:3px}
.field label.check,label.check{font-weight:400;display:flex;gap:6px;align-items:center}
input[type=text],input[type=email],input[type=password],input[type=number],input[type=date],input[type=datetime-local],input:not([type]),select,textarea{width:100%;padding:7px 9px;border:1px solid #c9cfdb;border-radius:6px;font:inherit;background:#fff}
input:focus,select:focus,textarea:focus,.btn:focus-visible{outline:2px solid #9db7ff;outline-offset:1px}
.has-err input,.has-err select,.has-err textarea{border-color:var(--bad)}.err-text{color:var(--bad);font-size:.85rem;margin-top:3px}
.sep{text-align:center;color:var(--mut);margin:12px 0;position:relative}.sep span{background:#fff;padding:0 10px;position:relative}
.sep:before{content:"";position:absolute;left:0;right:0;top:50%;border-top:1px solid var(--line)}
.demo{margin-top:16px;color:var(--mut);font-size:.9rem}
.sso-acc{margin-bottom:8px}
.grid{display:grid;grid-template-columns:repeat(12,1fr);gap:0 16px}
.span-1{grid-column:span 1}.span-2{grid-column:span 2}.span-3{grid-column:span 3}.span-4{grid-column:span 4}.span-5{grid-column:span 5}.span-6{grid-column:span 6}
.span-7{grid-column:span 7}.span-8{grid-column:span 8}.span-9{grid-column:span 9}.span-10{grid-column:span 10}.span-11{grid-column:span 11}.span-12{grid-column:span 12}
@media(max-width:700px){.grid>*{grid-column:span 12!important}}
.table{width:100%;border-collapse:collapse}
.table th,.table td{text-align:left;padding:8px 10px;border-bottom:1px solid var(--line)}
.table th a{color:var(--ink);text-decoration:none}.table td.num,.table th.num{text-align:right}
.scroll{overflow-x:auto}.actions{white-space:nowrap}
.pager{display:flex;gap:6px;align-items:center;margin-top:12px;flex-wrap:wrap}.pager span{margin-right:auto;color:var(--mut)}
.stat-label{color:var(--mut);font-size:.85rem}.stat-val{font-size:1.8rem;font-weight:700}
.bar{display:grid;grid-template-columns:140px 1fr 50px;gap:8px;align-items:center;margin:4px 0;font-size:.9rem}
.bar meter{width:100%}.bar b{text-align:right}.bar span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.img{max-width:100%;display:block}.img-ph{background:repeating-linear-gradient(45deg,#f0f2f7,#f0f2f7 10px,#e8ebf3 10px,#e8ebf3 20px);text-align:center;color:var(--mut);padding:30px}
.steps{display:flex;gap:6px;list-style:none;padding:0;margin:12px 0}
.steps li{flex:1;text-align:center;padding:6px;background:#eef1f7;border-radius:6px;font-size:.85rem;color:var(--mut)}
.steps li.on{background:var(--pri);color:#fff}.steps li.done{background:#e1f4e9;color:var(--ok)}
fieldset{border:1px solid var(--line);border-radius:6px;margin:0 0 12px}fieldset[hidden]{display:none}
.summary dt{font-weight:600;margin-top:8px}.summary dd{margin:0}
/* Builder */
.bld-tabs{display:flex;gap:4px;flex-wrap:wrap;border-bottom:2px solid var(--line);margin-bottom:8px}
.bld-tabs button{border:0;background:none;padding:10px 16px;cursor:pointer;font:inherit;color:var(--mut);border-bottom:3px solid transparent;margin-bottom:-2px}
.bld-tabs button.on{color:var(--pri-d);border-bottom-color:var(--pri);font-weight:600}
.bld-bar{display:flex;justify-content:space-between;font-size:.85rem;margin-bottom:10px}
.split{display:grid;grid-template-columns:220px 1fr;gap:16px;align-items:start}
.split.three{grid-template-columns:200px 1fr 300px}
@media(max-width:900px){.split,.split.three{grid-template-columns:1fr}}
.list{list-style:none;margin:0 0 10px;padding:0}.list li button{display:block;width:100%;text-align:left;padding:7px 10px;border:1px solid transparent;background:none;border-radius:6px;cursor:pointer;font:inherit}
.list li button.on{background:#eaf0ff;border-color:#c7d6ff}
.ftable{width:100%;border-collapse:collapse}.ftable th{text-align:left;font-size:.8rem;color:var(--mut);padding:4px}.ftable td{padding:3px}
.ftable input,.ftable select{padding:5px 6px}
.toolbar{display:flex;gap:8px;margin-bottom:12px;flex-wrap:wrap;align-items:center}
.toolbar .grow{flex:1}
.erd{width:100%;height:300px;background:#fafbfd;border:1px solid var(--line);border-radius:var(--r)}
.erd text{font:12px system-ui}.erd .t{font-weight:700}
.canvas{display:grid;grid-template-columns:repeat(12,1fr);gap:8px;min-height:260px;padding:10px;background:#fafbfd;border:2px dashed #c9cfdb;border-radius:var(--r);align-content:start}
.canvas.over{border-color:var(--pri);background:#f0f5ff}
.blk{border:1px solid #b9c7ee;background:#fff;border-radius:6px;padding:8px;cursor:pointer;min-height:64px}
.blk.sel{outline:2px solid var(--pri)}.blk b{display:block}.blk small{color:var(--mut)}
.blk .tools{display:flex;gap:3px;margin-top:6px}
.palette{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:12px}
.palette .chip{padding:5px 10px;border:1px solid #c9cfdb;border-radius:14px;background:#fff;cursor:grab;font-size:.9rem}
.matrix td,.matrix th{text-align:center;padding:5px 8px;border-bottom:1px solid var(--line)}.matrix td:first-child,.matrix th:first-child{text-align:left}
.matrix th[colspan]{background:#f4f6f9}
.urlrow{display:flex;gap:8px;align-items:center;margin-bottom:8px}.urlrow code{flex:1;padding:6px 8px;overflow-x:auto}
.steps-test{list-style:none;padding:0}.steps-test li{padding:4px 0}
.dirty{color:var(--warn)}
dialog{border:1px solid var(--line);border-radius:var(--r);max-width:720px;width:92%}
dialog pre{background:#111827;color:#e5e7eb;padding:12px;border-radius:6px;overflow:auto;max-height:55vh;font-size:.85rem}
.preview-wrap{margin:0 auto;transition:max-width .2s}.preview-wrap.tablet{max-width:720px}.preview-wrap.ponsel{max-width:380px}
.preview-wrap.ponsel .grid>*,.preview-wrap.tablet .grid>*{}
.pgrid{display:grid;grid-template-columns:repeat(12,1fr);gap:0 12px}
.preview-wrap.ponsel .pgrid>*{grid-column:span 12!important}
.warnbox{border:1px solid #f0c36d;background:#fff8e6;border-radius:6px;padding:10px;margin:8px 0}
.warnbox pre{margin:6px 0 0;white-space:pre-wrap}
/* F16 + responsive */
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.role-switch{display:flex;gap:6px;align-items:center}.role-switch select{width:auto;padding:3px 6px}
fieldset legend{font-weight:600;padding:0 6px}fieldset .check{margin:4px 0}
html{max-width:100%;overflow-x:hidden}body{max-width:100%}
.main,.card,.grid>*,.pgrid>*,.canvas>*,.split>*,.preview-wrap{min-width:0}
.scroll{max-width:100%;-webkit-overflow-scrolling:touch}
.scroll .table,.scroll .ftable{min-width:max-content}
.ftable input,.ftable select{min-width:90px}
.erd{max-width:100%}
.dirty,.urlrow code{overflow-wrap:anywhere}
.pgrid>*{overflow-wrap:anywhere}
.preview-wrap .scroll .table{min-width:max-content}
@media(max-width:700px){
  .topbar{padding:8px 12px}
  .main{padding:0 10px;margin:12px auto}
  .pgrid>*,.canvas>*{grid-column:span 12!important}
  .pgrid,.canvas{gap:8px}
  .bld-tabs{flex-wrap:nowrap;overflow-x:auto;-webkit-overflow-scrolling:touch}
  .bld-tabs button{white-space:nowrap;padding:10px 12px}
  .bld-bar{flex-direction:column;gap:2px}
  .toolbar>*{max-width:100%}
  .toolbar select{max-width:100%}
  .steps{flex-wrap:wrap}
  .bar{grid-template-columns:90px 1fr 40px}
  .card{padding:12px}
  .btn{padding:8px 12px}
  dialog{width:96%}
}
/* Sidebar aplikasi */
.shell{display:flex;min-height:100vh;align-items:stretch}
.content{flex:1;min-width:0;display:flex;flex-direction:column}
.content .main{width:100%;flex:1}
.sidebar{width:240px;flex:0 0 240px;background:#fff;border-right:1px solid var(--line);display:flex;flex-direction:column;position:sticky;top:0;height:100vh;z-index:30}
.side-head{display:flex;align-items:center;gap:8px;padding:12px 14px;border-bottom:1px solid var(--line)}
.side-head .brand{flex:1;min-width:0;white-space:nowrap;overflow:hidden}
.side-btn{border:1px solid var(--line);background:#fff;border-radius:6px;cursor:pointer;font:inherit;line-height:1;padding:7px 10px;color:var(--ink)}
.side-btn:hover{border-color:var(--pri)}.side-btn:focus-visible,.side-link:focus-visible{outline:2px solid #9db7ff;outline-offset:1px}
.side-close,.side-open{display:none}
.side-nav{flex:1;overflow-y:auto;padding:8px}
.side-title{font-size:.72rem;text-transform:uppercase;letter-spacing:.06em;color:var(--mut);padding:12px 10px 4px}
.side-link{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:6px;text-decoration:none;color:var(--mut)}
.side-link:hover,.side-link.on{background:#eaf0ff;color:var(--pri-d)}.side-link.on{font-weight:600}
.ico{display:inline-block;width:1.4em;text-align:center;flex:0 0 1.4em}
.lbl{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.side-foot{border-top:1px solid var(--line);padding:10px;display:flex;flex-direction:column;gap:8px}
.side-user .uname{font-weight:600;overflow-wrap:anywhere}
.side-foot .role-switch select{flex:1;min-width:0}
.side-logout .btn{display:flex;gap:8px;justify-content:center;align-items:center}
.overlay{position:fixed;inset:0;background:rgba(17,24,39,.45);z-index:25}
.overlay[hidden]{display:none}
@media(min-width:1024px){
  .side-collapsed .sidebar{width:64px;flex-basis:64px}
  .side-collapsed .side-head{flex-direction:column;padding:10px 6px}
  .side-collapsed .side-head .brand{display:none}
  .side-collapsed .side-title{height:1px;margin:8px 10px;padding:0;background:var(--line);font-size:0;overflow:hidden}
  .side-collapsed .side-link{justify-content:center;padding:8px 0}
  .side-collapsed .lbl,.side-collapsed .side-user,.side-collapsed .role-switch,.side-collapsed .side-role{display:none}
  .side-collapsed .side-logout .btn{padding:6px 0}
  .topbar{display:none}
  .overlay{display:none!important}
}
@media(max-width:1023.98px){
  .sidebar{position:fixed;top:0;left:0;bottom:0;height:auto;width:min(280px,85vw);transform:translateX(-100%);visibility:hidden;transition:transform .2s,visibility .2s}
  .drawer-open .sidebar{transform:none;visibility:visible}
  .drawer-open{overflow:hidden}
  .side-collapse{display:none}
  .side-close,.side-btn.side-open{display:inline-block}
  .topbar{position:sticky;top:0;z-index:20}
}
@media(prefers-reduced-motion:reduce){.sidebar{transition:none}}
.w5{width:5em}
