:root{
  --navy:#1F3A5F; --gold:#C08A2E; --teal:#2E7D6B; --red:#C0392B;
  --slate:#5B6B7C; --green:#4E8A3F; --purple:#6B4E8A;
  --board:#F6F7F4; --grid:#E3E7E0; --frame:#d8dbd4;
  --ink:#1b1b1b; --chrome:#ffffff; --chrome-2:#f2f3f0;
  --line:#dcded8; --txt:#26302b; --txt-2:#6b746e; --focus:#C08A2E;
  --shadow:0 1px 2px rgba(20,30,25,.08),0 6px 18px rgba(20,30,25,.10);
}
@media (prefers-color-scheme: dark){:root:where(:not([data-theme="light"])){
  --board:#161a1c; --grid:#282d30; --frame:#0c0e10;
  --ink:#eef0ec; --chrome:#1c2124; --chrome-2:#232a2e;
  --line:#313a3e; --txt:#e7eae7; --txt-2:#9aa4a0;
  --shadow:0 1px 2px rgba(0,0,0,.4),0 8px 22px rgba(0,0,0,.5);
}}
:root[data-theme="dark"]{
  --board:#161a1c; --grid:#282d30; --frame:#0c0e10;
  --ink:#eef0ec; --chrome:#1c2124; --chrome-2:#232a2e;
  --line:#313a3e; --txt:#e7eae7; --txt-2:#9aa4a0;
  --shadow:0 1px 2px rgba(0,0,0,.4),0 8px 22px rgba(0,0,0,.5);
}
*{box-sizing:border-box;margin:0}
html,body{height:100%}
body{
  font-family:"Microsoft JhengHei","Noto Sans TC",system-ui,-apple-system,"Segoe UI",sans-serif;
  color:var(--txt); background:var(--chrome);
  display:flex; flex-direction:column; height:100dvh; overflow:hidden;
  -webkit-user-select:none; user-select:none; touch-action:none;
}
/* ---------- toolbar ---------- */
.bar{display:flex; align-items:center; gap:10px; padding:9px 12px;
  background:var(--chrome); border-bottom:1px solid var(--line); flex-wrap:wrap; z-index:20}
.brand{font-weight:800; font-size:15px; color:var(--navy); letter-spacing:.02em; display:flex; align-items:center; gap:8px; padding-right:4px}
.brand .dot{width:10px;height:10px;border-radius:50%;background:var(--gold)}
:root[data-theme="dark"] .brand{color:#8fb4dd}
@media (prefers-color-scheme: dark){:root:where(:not([data-theme="light"])) .brand{color:#8fb4dd}}
.grp{display:flex; align-items:center; gap:4px; padding:3px; background:var(--chrome-2); border-radius:10px}
.sep{width:1px; height:26px; background:var(--line); margin:0 2px}
button.t{font:inherit; font-size:13px; font-weight:600; color:var(--txt); background:transparent;
  border:0; border-radius:8px; padding:7px 11px; cursor:pointer; display:flex; align-items:center; gap:6px; line-height:1}
button.t:hover{background:var(--chrome)}
button.t.on{background:var(--navy); color:#fff}
button.t svg{width:17px;height:17px;display:block}
.swatch{width:24px;height:24px;border-radius:7px;border:2px solid transparent;cursor:pointer;padding:0;background:var(--sw)}
.swatch.on{border-color:var(--txt); box-shadow:0 0 0 2px var(--chrome) inset}
.spacer{flex:1}
.hint{font-size:12px;color:var(--txt-2);white-space:nowrap}
@media (max-width:900px){.hint{display:none}}
/* ---------- main ---------- */
.stage{flex:1; display:flex; min-height:0}
.tray{width:212px; flex:0 0 212px; background:var(--chrome); border-right:1px solid var(--line);
  overflow-y:auto; padding:12px 12px 30px}
.tray h4{font-size:11px; text-transform:uppercase; letter-spacing:.09em; color:var(--txt-2);
  margin:16px 0 8px; font-weight:800}
.tray h4:first-child{margin-top:2px}
.chips{display:flex; flex-wrap:wrap; gap:6px}
.chip{font:inherit; font-size:12.5px; font-weight:700; color:#fff; border:0; border-radius:999px;
  padding:6px 11px; cursor:pointer; background:var(--c); box-shadow:var(--shadow); line-height:1.1}
.chip:hover{filter:brightness(1.08)}
.chip:active{transform:translateY(1px)}
.custom{display:flex; flex-direction:column; gap:8px; margin-top:8px}
.custom input{font:inherit; font-size:13px; padding:8px 10px; border:1px solid var(--line);
  border-radius:8px; background:var(--chrome-2); color:var(--txt); width:100%}
.custom .row{display:flex; gap:6px; align-items:center; flex-wrap:wrap}
.mini{width:20px;height:20px;border-radius:5px;border:2px solid transparent;cursor:pointer;background:var(--sw)}
.mini.on{border-color:var(--txt)}
.addbtn{font:inherit;font-size:13px;font-weight:700;color:#fff;background:var(--navy);border:0;border-radius:8px;padding:8px 12px;cursor:pointer}
.addbtn:hover{filter:brightness(1.08)}
/* ---------- board ---------- */
.board{position:relative; flex:1; min-width:0; overflow:hidden;
  background:var(--board);
  box-shadow:inset 0 0 0 1px var(--frame), inset 0 0 60px rgba(0,0,0,.02);}
.board.grid{background-image:
  linear-gradient(var(--grid) 1px,transparent 1px),
  linear-gradient(90deg,var(--grid) 1px,transparent 1px);
  background-size:34px 34px;}
canvas{position:absolute; inset:0; width:100%; height:100%; touch-action:none}
#bgcv{z-index:0; pointer-events:none}
#linkcv{z-index:1; pointer-events:none}
#cv{z-index:2}
.mag{position:absolute; color:#fff; font-weight:800; font-size:15px; padding:11px 15px;
  border-radius:11px; background:var(--c); box-shadow:0 2px 3px rgba(0,0,0,.18),0 7px 16px rgba(0,0,0,.20);
  cursor:grab; white-space:nowrap; line-height:1.15; max-width:260px;
  border-top:1px solid rgba(255,255,255,.28); touch-action:none; z-index:3; transform-origin:center}
.mag.dot{width:36px; height:36px; min-width:0; padding:0; border-radius:50%}
.mag.dot .label{display:none}
.mag.shape{min-width:72px; min-height:72px; padding:16px 20px; background:transparent!important; box-shadow:none; border:0; border-top:0;
  display:inline-flex; align-items:center; justify-content:center; white-space:normal; max-width:200px}
.mag.shape .fill{position:absolute; inset:0; background:var(--c); z-index:0; filter:drop-shadow(0 3px 5px rgba(0,0,0,.28))}
.mag.shape .label{position:relative; z-index:1; color:#fff; font-weight:800; font-size:13.5px; line-height:1.15; text-align:center}
.mag.shape.circle .fill{border-radius:50%}
.mag.shape.square .fill{border-radius:12px}
.mag.shape.diamond{padding:20px 30px}
.mag.shape.diamond .fill{clip-path:polygon(50% 0%,100% 50%,50% 100%,0% 50%)}
.mag.shape.hex .fill{clip-path:polygon(25% 5%,75% 5%,100% 50%,75% 95%,25% 95%,0% 50%)}
.mag.shape.tri{padding:28px 24px 14px}
.mag.shape.tri .fill{clip-path:polygon(50% 0%,0% 100%,100% 100%)}
.mag.shape.star{padding:24px 26px}
.mag.shape.star .fill{clip-path:polygon(50% 0%,61% 35%,98% 35%,68% 57%,79% 91%,50% 70%,21% 91%,32% 57%,2% 35%,39% 35%)}
.mag.shape.heart{padding:22px 22px 26px}
.mag.shape.heart .fill{clip-path:polygon(50% 100%,10% 60%,3% 38%,15% 18%,35% 18%,50% 35%,65% 18%,85% 18%,97% 38%,90% 60%)}
.mag.z{background:transparent; color:var(--txt); border:2.5px dashed var(--c);
  box-shadow:none; border-top:2.5px dashed var(--c); font-size:15px; font-weight:800;
  display:flex; align-items:flex-start; justify-content:center; padding-top:9px;}
.mag.z b{background:var(--c); color:#fff; padding:5px 12px; border-radius:8px; font-size:14px}
.mag.drag{cursor:grabbing; box-shadow:0 6px 10px rgba(0,0,0,.22),0 18px 34px rgba(0,0,0,.28); z-index:50}
.mag.sel{outline:2.5px solid var(--focus); outline-offset:3px}
.mag .label[contenteditable="true"]{cursor:text; outline:2px solid var(--focus); outline-offset:2px; border-radius:4px}
.mag .x{position:absolute; top:-9px; right:-9px; width:20px; height:20px; border-radius:50%;
  background:#e23b3b; color:#fff; font-size:13px; line-height:20px; text-align:center;
  display:none; cursor:pointer; box-shadow:0 1px 3px rgba(0,0,0,.3)}
.mag:hover .x,.mag.sel .x{display:block}
.mag.z .x{top:2px; right:2px}
/* palette that floats when magnet selected */
.recolor{position:absolute; display:none; gap:6px; padding:7px; background:var(--chrome);
  border:1px solid var(--line); border-radius:10px; box-shadow:var(--shadow); z-index:60}
.recolor.show{display:flex}
.recolor .mini{width:22px;height:22px}
.recolor .div{width:1px; align-self:stretch; background:var(--line); margin:0 3px}
.recolor .sp{width:25px; height:25px; border-radius:6px; border:1px solid var(--line); background:var(--chrome-2);
  color:var(--txt); font-size:14px; line-height:1; cursor:pointer; display:flex; align-items:center; justify-content:center; padding:0}
.recolor .sp:hover{background:var(--chrome); border-color:var(--focus)}
.linkdel{position:absolute; display:none; width:22px; height:22px; border:0; border-radius:50%;
  background:#e23b3b; color:#fff; font-size:14px; line-height:22px; text-align:center; cursor:pointer;
  z-index:61; box-shadow:0 1px 3px rgba(0,0,0,.35); padding:0}
.marquee{position:absolute; display:none; border:1.5px dashed #1F3A5F; background:rgba(31,58,95,.10); z-index:55; pointer-events:none}
.mag .x{transform:scale(calc(1/var(--s,1)))}
.rzbox{position:absolute; display:none; border:1.5px solid #C08A2E; z-index:58; pointer-events:none}
.rzh{position:absolute; width:14px; height:14px; background:#fff; border:2px solid #C08A2E; border-radius:3px; pointer-events:auto; z-index:59; touch-action:none}
.rzh.tl{left:-8px; top:-8px; cursor:nwse-resize} .rzh.tr{right:-8px; top:-8px; cursor:nesw-resize}
.rzh.bl{left:-8px; bottom:-8px; cursor:nesw-resize} .rzh.br{right:-8px; bottom:-8px; cursor:nwse-resize}
.mag.linksrc{outline:2.5px solid #C08A2E; outline-offset:3px}
body.linking .mag{cursor:crosshair}
body.linking .board{cursor:crosshair}
/* present mode */
body.present .tray{display:none}
body.present .bar .grp.hidep,body.present .bar .brand span,body.present .bar .hint{display:none}
.empty{position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
  pointer-events:none; color:var(--txt-2); font-size:14px; text-align:center; opacity:.8}
button:focus-visible,.swatch:focus-visible,.chip:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
@media (prefers-reduced-motion:reduce){*{transition:none!important}}
