:root{
  --bg:#0f1420; --bg2:#161d2c; --bg3:#1d2637; --line:#2a3550;
  --txt:#dfe6f3; --muted:#8b9ab8; --accent:#3ddc97; --accent2:#4aa8ff;
  --warn:#ff7a7a; --chip:#233049; --shadow:0 6px 24px rgba(0,0,0,.35);
  --tag:#7ee787; --attr:#79c0ff; --val:#ffa657; --cmt:#6b7a99; --ent:#d2a8ff;
}
body.light{
  --bg:#eef1f6; --bg2:#ffffff; --bg3:#f5f7fb; --line:#d8dee9;
  --txt:#1d2433; --muted:#5b6779; --accent:#0f9d63; --accent2:#1668d1;
  --chip:#e7ecf5; --shadow:0 6px 20px rgba(30,44,80,.12);
  --tag:#116329; --attr:#0550ae; --val:#a1440a; --cmt:#8a94a6; --ent:#7c3aed;
}
*{box-sizing:border-box}
html,body{height:100%}
body{
  margin:0; background:var(--bg); color:var(--txt);
  font:14px/1.45 system-ui,-apple-system,"Segoe UI",Roboto,Ubuntu,sans-serif;
  display:flex; flex-direction:column;
}
button,input,select,textarea{font-family:inherit}

/* ── top bar ── */
.topbar{
  display:flex; align-items:center; gap:16px; flex-wrap:wrap;
  padding:10px 14px; background:var(--bg2); border-bottom:1px solid var(--line);
}
.brand{display:flex; align-items:center; gap:10px}
.logo{
  display:grid; place-items:center; width:38px; height:38px; border-radius:10px;
  background:linear-gradient(135deg,var(--accent),var(--accent2)); color:#04121a;
  font-weight:800; font-size:15px;
}
.brand h1{margin:0; font-size:16px; letter-spacing:.2px}
.brand p{margin:0; font-size:11px; color:var(--muted)}
.top-actions{display:flex; align-items:center; gap:6px; flex-wrap:wrap; margin-left:auto}
.divider{width:1px; height:22px; background:var(--line); margin:0 4px}

.btn{
  background:var(--bg3); color:var(--txt); border:1px solid var(--line);
  padding:7px 11px; border-radius:8px; cursor:pointer; font-size:13px; white-space:nowrap;
  transition:.15s;
}
.btn:hover{border-color:var(--accent2); transform:translateY(-1px)}
.btn:active{transform:none}
.btn.small{padding:5px 9px; font-size:12px}
.btn.icon-only{padding:7px 9px}
.btn-primary{
  background:linear-gradient(135deg,var(--accent),var(--accent2)); color:#04121a;
  border:none; font-weight:700;
}
.link-btn{background:none;border:none;color:var(--accent2);cursor:pointer;font-size:12px;text-decoration:underline}
.spacer{flex:1}

/* ── workspace ── */
.workspace{display:flex; flex:1 1 auto; min-height:320px; overflow:hidden}
.pane{display:flex; flex-direction:column; min-width:220px; overflow:hidden; background:var(--bg2)}
#paneVisual{flex:1 1 50%}
#paneSource{flex:1 1 50%}
.splitter{width:6px; cursor:col-resize; background:var(--line); flex:0 0 6px}
.splitter:hover{background:var(--accent2)}

.pane-head{
  display:flex; align-items:center; gap:8px; flex-wrap:wrap;
  padding:6px 10px; background:var(--bg3); border-bottom:1px solid var(--line);
}
.pane-title{font-size:12px; font-weight:700; color:var(--muted); letter-spacing:.4px}
.mini-toolbar{display:flex; gap:3px; flex-wrap:wrap; margin-left:auto}
.mini-toolbar button{
  background:var(--bg2); border:1px solid var(--line); color:var(--txt);
  width:28px; height:26px; border-radius:6px; cursor:pointer; font-size:12px; padding:0;
}
.mini-toolbar button:hover{border-color:var(--accent)}
.mini-toolbar select{
  background:var(--bg2); border:1px solid var(--line); color:var(--txt);
  border-radius:6px; height:26px; font-size:12px;
}
.stats{display:flex; gap:12px; margin-left:auto; font-size:11px; color:var(--muted); align-items:center}

.visual{
  flex:1; overflow:auto; padding:16px 18px; outline:none; background:var(--bg2);
  font-size:15px; line-height:1.55;
}
body.light .visual{background:#fff}
.visual img{max-width:100%}
.visual table{border-collapse:collapse}
.visual td,.visual th{border:1px solid var(--line); padding:4px 8px}
.visual blockquote{border-left:3px solid var(--accent); margin:8px 0; padding:2px 12px; color:var(--muted)}

/* ── code editor ── */
.editor-shell{flex:1; display:flex; overflow:hidden; background:var(--bg2); position:relative}
.gutter{
  padding:10px 8px 10px 12px; text-align:right; color:var(--cmt); background:var(--bg3);
  border-right:1px solid var(--line); user-select:none; overflow:hidden; white-space:pre;
  font:13px/1.5 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; min-width:44px;
}
.code-area{position:relative; flex:1; overflow:hidden}
.highlight,#source{
  margin:0; padding:10px 14px; border:0; width:100%; height:100%;
  font:13px/1.5 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  white-space:pre; overflow:auto; tab-size:2;
}
.highlight{position:absolute; inset:0; pointer-events:none; color:var(--txt)}
#source{
  position:absolute; inset:0; background:transparent; color:transparent;
  caret-color:var(--accent); resize:none; outline:none;
}
#source::selection{background:rgba(74,168,255,.35)}
body.wrap .highlight, body.wrap #source{white-space:pre-wrap; word-break:break-word}
body.wrap .gutter{display:none}
.tok-tag{color:var(--tag)}
.tok-attr{color:var(--attr)}
.tok-val{color:var(--val)}
.tok-cmt{color:var(--cmt); font-style:italic}
.tok-ent{color:var(--ent)}
.tok-doc{color:var(--muted)}

/* ── cleaner tiles ── */
.cleaners,.custom{background:var(--bg2); border-top:1px solid var(--line)}
.cleaners-head,.custom-head{
  display:flex; align-items:center; gap:10px; flex-wrap:wrap; padding:8px 14px;
  border-bottom:1px solid var(--line); font-size:13px;
}
.hint{color:var(--muted); font-size:12px}
.tiles{
  display:grid; grid-template-columns:repeat(auto-fill,minmax(190px,1fr));
  gap:8px; padding:10px 14px; max-height:210px; overflow:auto;
}
.tile{
  display:flex; align-items:center; gap:8px; background:var(--bg3);
  border:1px solid var(--line); border-radius:9px; padding:7px 9px;
}
.tile input[type=checkbox]{accent-color:var(--accent); width:15px; height:15px; flex:0 0 auto}
.tile .t-body{flex:1; min-width:0}
.tile .t-name{font-size:12.5px; font-weight:600; display:block; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.tile .t-desc{font-size:10.5px; color:var(--muted); display:block; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.tile .run{
  background:var(--chip); border:1px solid var(--line); color:var(--accent);
  border-radius:6px; width:26px; height:26px; cursor:pointer; flex:0 0 auto; font-size:11px;
}
.tile .run:hover{background:var(--accent); color:#04121a}
.tile.star{border-color:var(--accent)}

/* ── custom settings ── */
.custom-body{padding:12px 14px 16px}
.custom-body.hidden{display:none}
.grid{display:grid; grid-template-columns:repeat(auto-fill,minmax(280px,1fr)); gap:12px}
.card{background:var(--bg3); border:1px solid var(--line); border-radius:11px; padding:11px 12px}
.card h3{margin:0 0 9px; font-size:13px}
.field{display:flex; flex-direction:column; gap:4px; margin-bottom:8px; font-size:12px; color:var(--muted)}
.field.inline{flex-direction:row; align-items:center; gap:8px}
.field input[type=text],.field input[type=number],.field select,.rule-row input,.rule-row select{
  background:var(--bg2); border:1px solid var(--line); color:var(--txt);
  border-radius:7px; padding:6px 8px; font-size:12.5px; width:100%;
}
.field.inline input[type=number]{width:80px}
.chk{display:flex; align-items:center; gap:7px; font-size:12.5px; margin:5px 0; cursor:pointer}
.chk.tiny{font-size:11px; margin:0}
.chk input{accent-color:var(--accent)}
.note{font-size:11px; color:var(--muted); margin:8px 0 6px}
code{background:var(--chip); padding:1px 4px; border-radius:4px; font-size:11.5px}
.rule-list{display:flex; flex-direction:column; gap:6px; margin-bottom:8px}
/* ── rule rows: explicit 2-line grid so nothing orphans onto its own line ── */
.rule-row{
  display:grid; gap:5px 6px; align-items:center;
  background:var(--bg2); border:1px solid var(--line); border-radius:8px; padding:6px 7px;
}
.rule-row input[type=text]{min-width:0; width:100%}
.rule-row input[type=checkbox]{accent-color:var(--accent); width:15px; height:15px; justify-self:center}
.rule-row .del{justify-self:center}

/* custom element rules:  [on][selector][x]
                          [   action    ]   */
#ruleList .rule-row{
  grid-template-columns:auto 1fr auto;
  grid-template-areas:"chk sel del" "act act act";
}
#ruleList .rule-row > :nth-child(1){grid-area:chk}
#ruleList .rule-row > :nth-child(2){grid-area:sel}
#ruleList .rule-row > :nth-child(3){grid-area:act; width:100%; max-width:none}
#ruleList .rule-row > :nth-child(4){grid-area:del}

/* find & replace:  [on][find][replace][x]
                        [re][Aa]          */
#replaceList .rule-row{
  grid-template-columns:auto 1fr 1fr auto;
  grid-template-areas:"chk find to del" "chk opts opts del";
}
#replaceList .rule-row > :nth-child(1){grid-area:chk}
#replaceList .rule-row > :nth-child(2){grid-area:find}
#replaceList .rule-row > :nth-child(3){grid-area:to}
#replaceList .rule-row > :nth-child(4){grid-area:opts; justify-self:start}
#replaceList .rule-row > :nth-child(5){grid-area:opts; justify-self:start; margin-left:52px}
#replaceList .rule-row > :nth-child(6){grid-area:del}
.rule-row .del{background:none; border:none; color:var(--warn); cursor:pointer; font-size:15px; padding:0 3px}
.rule-row label.mini{display:flex; align-items:center; gap:3px; font-size:11px; color:var(--muted); white-space:nowrap}
.preset-bar{display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-top:12px;
  border-top:1px dashed var(--line); padding-top:10px}
.preset-bar .field{margin:0}

/* ── toast ── */
.toast{
  position:fixed; left:50%; bottom:24px; transform:translate(-50%,20px);
  background:var(--bg3); color:var(--txt); border:1px solid var(--accent);
  padding:9px 16px; border-radius:10px; box-shadow:var(--shadow);
  opacity:0; pointer-events:none; transition:.22s; z-index:99; font-size:13px; max-width:80vw;
}
.toast.show{opacity:1; transform:translate(-50%,0)}

@media (max-width:860px){
  .workspace{flex-direction:column}
  .splitter{width:auto; height:6px; cursor:row-resize; flex:0 0 6px}
  .pane{min-height:220px}
  .tiles{max-height:none}
}

/* notice shown when storage is unavailable (sandboxed preview) */
.storage-note{
  position:fixed; right:14px; bottom:14px; max-width:330px; z-index:98;
  background:var(--bg3); color:var(--txt); border:1px solid var(--accent2);
  border-radius:10px; padding:10px 13px; font-size:12px; line-height:1.4;
  box-shadow:var(--shadow); cursor:pointer; opacity:0; transform:translateY(10px);
  transition:.25s;
}
.storage-note.show{opacity:1; transform:none}
