/* ============================================================
   CODEFLOW : LOGIC ANIMATOR
   Industrial HMI / SCADA terminal aesthetic — dark cyberpunk
   ============================================================ */
:root{
  --void:#04070c;
  --steel:#0b131d;
  --steel2:#111c28;
  --line:#1e3346;
  --ink:#cfe3f2;
  --dim:#6d8ba3;
  --neon:#26ff9c;
  --neon-d:#0b6b45;
  --cyan:#3ad9ff;
  --amber:#ffb627;
  --red:#ff3d5f;
  --violet:#a06bff;
  --mono:"SFMono-Regular",Consolas,"Roboto Mono","Courier New",monospace;
  --thai:"Kanit","Noto Sans Thai","Sarabun","Segoe UI",system-ui,sans-serif;
}
*{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent}
html,body{height:100%}
body{
  background:var(--void);
  color:var(--ink);
  font-family:var(--thai);
  overflow:hidden;
  user-select:none;
  cursor:default;
}
/* ambient grid + vignette */
#bg{position:fixed;inset:0;z-index:0;pointer-events:none;
  background:
    radial-gradient(ellipse at 50% -10%, rgba(58,217,255,.10), transparent 60%),
    radial-gradient(ellipse at 90% 110%, rgba(38,255,156,.07), transparent 55%),
    repeating-linear-gradient(0deg, transparent 0 39px, rgba(30,51,70,.35) 39px 40px),
    repeating-linear-gradient(90deg, transparent 0 39px, rgba(30,51,70,.28) 39px 40px),
    var(--void);
  animation:drift 40s linear infinite;
}
@keyframes drift{to{background-position:0 0,0 0,0 400px,400px 0,0 0}}
#scan{position:fixed;inset:0;z-index:60;pointer-events:none;
  background:repeating-linear-gradient(180deg,rgba(0,0,0,.18) 0 1px,transparent 1px 3px);
  mix-blend-mode:multiply;opacity:.5}

#app{position:relative;z-index:2;height:100%;display:flex;flex-direction:column}

/* ---------- TOP BAR ---------- */
.topbar{
  display:flex;align-items:center;gap:14px;padding:8px 14px;
  border-bottom:1px solid var(--line);
  background:linear-gradient(180deg,rgba(17,28,40,.95),rgba(11,19,29,.8));
  flex:0 0 auto;
}
.brand{display:flex;align-items:baseline;gap:9px;letter-spacing:.5px}
.brand b{font-family:var(--mono);font-size:16px;font-weight:700;color:var(--neon);text-shadow:0 0 14px rgba(38,255,156,.5)}
.brand span{font-family:var(--mono);font-size:10px;color:var(--dim);letter-spacing:2px}
.stats{display:flex;gap:8px;margin-left:auto;flex-wrap:wrap;justify-content:flex-end}
.chip{
  font-family:var(--mono);font-size:10px;line-height:1;color:var(--dim);
  border:1px solid var(--line);background:rgba(6,12,19,.7);
  padding:6px 9px;border-radius:3px;min-width:60px
}
.chip i{display:block;font-style:normal;font-size:9px;letter-spacing:1.4px;opacity:.65;margin-bottom:4px}
.chip b{font-size:14px;color:var(--ink);font-weight:600;letter-spacing:.5px}
.chip.acc b{color:var(--neon)} .chip.warn b{color:var(--amber)} .chip.hot b{color:var(--red)}
.chip.id b{font-size:11px;color:var(--cyan)}

/* integrity bar */
.integrity{width:112px}
.ibar{height:5px;background:#0a1119;border:1px solid var(--line);border-radius:2px;overflow:hidden;margin-top:5px}
.ibar>i{display:block;height:100%;width:100%;background:linear-gradient(90deg,var(--neon),var(--cyan));transition:width .45s cubic-bezier(.2,.9,.3,1)}
.ibar.low>i{background:linear-gradient(90deg,var(--red),var(--amber))}

/* ---------- STAGE ---------- */
.stage{flex:1 1 auto;display:grid;grid-template-columns:minmax(0,1.08fr) minmax(0,1fr);gap:10px;padding:10px;min-height:0}
.panel{
  border:1px solid var(--line);border-radius:5px;background:
   linear-gradient(180deg,rgba(17,28,40,.72),rgba(7,13,20,.86));
  display:flex;flex-direction:column;min-height:0;position:relative;overflow:hidden
}
.panel::before{content:"";position:absolute;top:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,rgba(58,217,255,.6),transparent)}
.phead{
  display:flex;align-items:center;gap:8px;padding:7px 11px;border-bottom:1px solid var(--line);
  font-family:var(--mono);font-size:10px;letter-spacing:2px;color:var(--dim);flex:0 0 auto
}
.phead .dot{width:6px;height:6px;border-radius:50%;background:var(--neon);box-shadow:0 0 8px var(--neon);animation:pulse 1.8s infinite}
@keyframes pulse{50%{opacity:.25}}
.phead em{margin-left:auto;font-style:normal;color:var(--cyan);letter-spacing:1px}

/* ---------- MISSION BRIEF ---------- */
.brief{padding:10px 12px;border-bottom:1px solid var(--line);flex:0 0 auto;background:rgba(4,9,15,.5);max-height:52%;overflow-y:auto;scrollbar-width:thin}
.brief h2{font-size:14px;font-weight:600;color:var(--ink);letter-spacing:.2px;display:flex;align-items:center;gap:7px}
.brief h2 u{text-decoration:none;font-family:var(--mono);font-size:9px;color:var(--void);background:var(--neon);padding:2px 6px;border-radius:2px;letter-spacing:1px}
.brief p{font-size:12.5px;color:#8fb0c8;margin-top:5px;line-height:1.55}
.glabel{margin-top:9px;font-family:var(--mono);font-size:9px;letter-spacing:2px;color:var(--dim);
  display:flex;align-items:center;gap:8px}
.glabel::after{content:"";flex:1;height:1px;background:var(--line)}
.goals{margin-top:5px;display:flex;flex-direction:column;gap:3px}
.goals li{list-style:none;font-size:12.5px;color:#b6d2e6;display:flex;gap:8px;line-height:1.55;margin-top:3px}
.goals li b{font-family:var(--mono);color:var(--cyan);font-weight:400;flex:0 0 auto;font-size:10px;padding-top:2px}
.rulebox{margin-top:8px;padding:7px 10px;border-left:3px solid var(--amber);border-radius:3px;
  background:rgba(255,182,39,.07);font-size:11.5px;line-height:1.5;color:#e0c78a}
.meta{display:flex;gap:6px;flex-wrap:wrap;margin-top:8px}
.meta span{font-family:var(--mono);font-size:9px;letter-spacing:.8px;color:var(--dim);
  border:1px solid var(--line);border-radius:2px;padding:3px 7px}
.meta span.hot{color:var(--amber);border-color:#4a3a14}
.checks{margin-top:16px;display:flex;flex-direction:column;gap:6px}
.checks div{display:flex;align-items:center;gap:9px;font-size:12px;color:var(--dim);
  border:1px solid var(--line);border-radius:3px;padding:8px 11px;background:rgba(8,15,23,.6)}
.checks div b{font-family:var(--mono);font-size:13px;flex:0 0 auto;width:16px;text-align:center}
.checks div.ok{color:#9fc0d8;border-color:var(--neon-d)}.checks div.ok b{color:var(--neon)}
.checks div.no{color:#ffc2ce;border-color:#4a2430}.checks div.no b{color:var(--red)}
.checks div.wait b{color:var(--amber)}
canvas#sim{flex:1 1 auto;width:100%;min-height:0;display:block}

/* ---------- FLOWCHART ---------- */
.flowwrap{flex:1 1 auto;overflow-y:auto;overflow-x:hidden;padding:10px 12px;min-height:0;scrollbar-width:thin;scrollbar-color:var(--line) transparent}
.flowwrap::-webkit-scrollbar{width:6px}.flowwrap::-webkit-scrollbar-thumb{background:var(--line);border-radius:3px}
.rail{display:flex;flex-direction:column;gap:0}
.slotrow{display:flex;align-items:center;gap:8px}
.snum{font-family:var(--mono);font-size:10px;color:var(--dim);width:20px;text-align:right;flex:0 0 auto}
.slot{
  flex:1 1 auto;min-height:44px;border:1px dashed #2a4560;border-radius:4px;
  background:rgba(8,15,23,.55);display:flex;align-items:center;padding:4px;
  transition:border-color .18s,background .18s,box-shadow .18s
}
.slot.hot{border-color:var(--cyan);background:rgba(58,217,255,.09);box-shadow:inset 0 0 22px rgba(58,217,255,.14)}
.slot.exec{border-style:solid;border-color:var(--amber);box-shadow:0 0 0 1px var(--amber),0 0 20px rgba(255,182,39,.28)}
.slot.ok{border-style:solid;border-color:var(--neon-d);background:rgba(38,255,156,.05)}
.slot.bad{border-style:solid;border-color:var(--red);animation:shake .38s}
@keyframes shake{0%,100%{transform:translateX(0)}20%{transform:translateX(-7px)}40%{transform:translateX(6px)}60%{transform:translateX(-4px)}80%{transform:translateX(3px)}}
.slot:empty::after{content:"วางบล็อกคำสั่งที่นี่";font-size:11px;color:#3f5f7c;font-family:var(--thai);padding-left:8px}
.link{height:14px;margin-left:28px;width:1px;background:linear-gradient(180deg,var(--line),#2a4560);position:relative}
.link::after{content:"";position:absolute;bottom:0;left:-3px;border-left:3.5px solid transparent;border-right:3.5px solid transparent;border-top:5px solid #2a4560}

/* ---------- BLOCKS ---------- */
.block{
  display:flex;align-items:center;gap:8px;width:100%;
  padding:8px 10px;border-radius:3px;cursor:grab;
  border:1px solid var(--line);border-left:3px solid var(--cyan);
  background:linear-gradient(180deg,#16273a,#0e1a27);
  font-size:12.5px;line-height:1.25;color:var(--ink);
  box-shadow:0 2px 0 rgba(0,0,0,.4);
  transition:transform .12s,box-shadow .12s,border-color .18s,background .3s;
  position:relative;
}
.block .ic{font-size:14px;flex:0 0 auto;width:18px;text-align:center;filter:saturate(1.2)}
.block .tx{flex:1 1 auto;min-width:0}
.block .tx small{display:block;font-family:var(--thai);font-size:10.5px;line-height:1.35;letter-spacing:0;color:#7fa3bd;margin-top:3px}
.block[data-kind="cond"]{border-left-color:var(--amber)}
.block[data-kind="io"]{border-left-color:var(--violet)}
.block[data-kind="act"]{border-left-color:var(--cyan)}
.palette .block:hover{transform:translateY(-2px);box-shadow:0 6px 16px rgba(0,0,0,.55);border-color:#2f5170}
.block.locked{
  cursor:not-allowed;border-color:var(--neon-d);border-left-color:var(--neon);
  background:linear-gradient(180deg,#0e2b21,#08201a);color:#9dffd2
}
.block.locked::after{content:"✔ LOCKED";position:absolute;right:9px;font-family:var(--mono);font-size:8px;letter-spacing:1px;color:var(--neon)}
.block.wrong{border-color:var(--red);border-left-color:var(--red);background:linear-gradient(180deg,#33131c,#210b12);color:#ffc2ce}
.block.dragging{opacity:.28}
.block.hint{animation:hintPulse 1.1s ease-in-out infinite}
@keyframes hintPulse{0%,100%{box-shadow:0 0 0 0 rgba(38,255,156,.55)}50%{box-shadow:0 0 0 7px rgba(38,255,156,0)}}
#ghost{position:fixed;z-index:80;pointer-events:none;width:250px;transform:translate(-50%,-50%) rotate(-1.5deg) scale(1.03);filter:drop-shadow(0 12px 22px rgba(0,0,0,.65))}
#ghost .block{cursor:grabbing;border-color:var(--cyan)}

/* ---------- PALETTE ---------- */
.paltitle{display:flex;align-items:center;gap:8px;margin:14px 0 8px;font-family:var(--mono);font-size:9.5px;letter-spacing:2px;color:var(--dim)}
.paltitle::after{content:"";flex:1;height:1px;background:var(--line)}
.palette{display:flex;flex-direction:column;gap:6px;min-height:52px;padding:2px;border-radius:4px;transition:background .18s}
.palette.hot{background:rgba(58,217,255,.06)}
.warnline{font-size:10.5px;color:var(--dim);margin-top:9px;font-family:var(--mono);letter-spacing:.3px;display:flex;gap:6px;align-items:flex-start;line-height:1.5}
.warnline b{color:var(--amber);font-weight:400}

/* ---------- CONTROLS ---------- */
.ctl{flex:0 0 auto;display:flex;gap:7px;padding:9px 12px;border-top:1px solid var(--line);background:rgba(4,9,15,.7)}
button{
  font-family:var(--mono);font-size:11px;letter-spacing:1.6px;
  border:1px solid var(--line);background:#101d2a;color:var(--ink);
  padding:10px 14px;border-radius:3px;cursor:pointer;transition:.15s;flex:0 0 auto
}
button:hover:not(:disabled){border-color:var(--cyan);color:#fff;background:#16283a}
button:disabled{opacity:.35;cursor:not-allowed}
button:focus-visible{outline:2px solid var(--cyan);outline-offset:2px}
.btn-run{flex:1 1 auto;background:linear-gradient(180deg,#0f4a34,#0a2e21);border-color:var(--neon-d);color:var(--neon);font-weight:700}
.btn-run.cancel{background:linear-gradient(180deg,#5a1424,#38101a);border-color:#7a2436;color:#ff8fa3}
.btn-run.cancel:hover{border-color:var(--red);color:#fff;box-shadow:0 0 22px rgba(255,61,95,.3)}
.btn-run:hover:not(:disabled){background:linear-gradient(180deg,#13674699,#0d3d2b);border-color:var(--neon);box-shadow:0 0 22px rgba(38,255,156,.28);color:#eafff5}
.btn-hint{color:var(--amber);border-color:#4a3a14}
.mini{padding:8px 11px;font-size:10px;letter-spacing:1px;border-color:#4a2430;color:#ff8fa3;background:#1a1018;margin-left:4px}
.mini:hover{border-color:var(--red);color:#fff;background:#26141c}

/* ---------- CAMERA ---------- */
/* กล้องเต็มจอ: วิดีโอเป็นฉากหลัง โครงมือลอยทับ UI */
#cam{position:fixed;inset:0;z-index:1;overflow:hidden;display:none;background:#03060a}
#cam.on{display:block}
#cam video{width:100%;height:100%;object-fit:fill;display:block;
  transform:scaleX(-1.47) scaleY(1.43);opacity:var(--camop,.2);filter:saturate(.55) contrast(1.08)}
#camCv{position:fixed;inset:0;z-index:78;pointer-events:none;display:none;opacity:.85}
#camCv.on{display:block}
#camHud{position:fixed;left:12px;bottom:12px;z-index:78;display:none;align-items:center;gap:9px;
  font-family:var(--mono);font-size:10px;letter-spacing:1px;padding:7px 10px;border:1px solid var(--line);
  border-radius:4px;background:rgba(4,9,15,.88);color:var(--dim)}
#camHud.on{display:flex}
#camHud b{color:var(--neon);font-weight:600}
#camHud button{padding:3px 7px;font-size:11px;letter-spacing:0}
/* เคอร์เซอร์มือ: ใหญ่ เห็นชัดข้ามพื้นหลังทุกแบบ */
#handCursor{position:fixed;z-index:79;width:66px;height:66px;margin:-33px 0 0 -33px;pointer-events:none;display:none}
#handCursor.on{display:block}
#handCursor .ring{position:absolute;inset:0;border:3px solid var(--cyan);border-radius:50%;
  transition:transform .09s,border-color .09s,box-shadow .09s;
  box-shadow:0 0 22px rgba(58,217,255,.65),inset 0 0 18px rgba(58,217,255,.28)}
#handCursor .ring::before,#handCursor .ring::after{content:"";position:absolute;background:var(--cyan);opacity:.85}
#handCursor .ring::before{left:50%;top:-13px;width:2px;height:9px;margin-left:-1px}
#handCursor .ring::after{left:50%;bottom:-13px;width:2px;height:9px;margin-left:-1px}
#handCursor .core{position:absolute;left:50%;top:50%;width:9px;height:9px;margin:-4.5px;background:#fff;
  border-radius:50%;box-shadow:0 0 12px #fff}
#handCursor .tip{position:absolute;left:50%;top:100%;transform:translateX(-50%);margin-top:9px;white-space:nowrap;
  font-family:var(--thai);font-size:11px;color:var(--cyan);background:rgba(4,9,15,.85);
  padding:3px 9px;border-radius:3px;border:1px solid var(--line)}
#handCursor.pinch .ring{transform:scale(.46);border-color:var(--neon);
  box-shadow:0 0 34px var(--neon),inset 0 0 20px rgba(38,255,156,.4)}
#handCursor.pinch .tip{color:var(--neon);border-color:var(--neon-d)}

/* ---------- OVERLAY / MENU ---------- */
.ov{position:fixed;inset:0;z-index:70;display:none;align-items:center;justify-content:center;padding:18px;
  background:radial-gradient(ellipse at center,rgba(4,10,16,.88),rgba(2,4,7,.97));backdrop-filter:blur(7px)}
.ov.on{display:flex}
.card{width:min(760px,100%);max-height:94vh;overflow-y:auto;border:1px solid var(--line);border-radius:6px;
  background:linear-gradient(180deg,rgba(17,28,40,.97),rgba(6,11,18,.99));padding:24px 26px;position:relative}
.card::before{content:"";position:absolute;top:0;left:0;right:0;height:2px;background:linear-gradient(90deg,var(--neon),var(--cyan),var(--violet))}
.title{font-family:var(--mono);font-size:clamp(24px,5vw,42px);font-weight:700;letter-spacing:-1px;line-height:1;color:#fff}
.title span{color:var(--neon);text-shadow:0 0 28px rgba(38,255,156,.45)}
.sub{font-family:var(--mono);font-size:10px;letter-spacing:3.5px;color:var(--dim);margin-top:8px}
.lead{font-size:13px;color:#9fc0d8;line-height:1.65;margin-top:14px}
.grp{margin-top:18px}
.grp>label{display:block;font-family:var(--mono);font-size:9.5px;letter-spacing:2px;color:var(--dim);margin-bottom:7px}
.opts{display:flex;gap:6px;flex-wrap:wrap}
.opt{
  padding:9px 13px;border:1px solid var(--line);border-radius:3px;background:#0d1826;cursor:pointer;
  font-size:12px;transition:.15s;color:var(--dim);flex:1 1 auto;text-align:center;min-width:96px
}
.opt small{display:block;font-family:var(--mono);font-size:8.5px;letter-spacing:1px;opacity:.7;margin-top:3px}
.opt:hover{border-color:#2f5170;color:var(--ink)}
.opt.sel{border-color:var(--neon);background:rgba(38,255,156,.1);color:var(--neon);box-shadow:inset 0 0 18px rgba(38,255,156,.1)}
input[type=text]{
  width:100%;background:#0a121c;border:1px solid var(--line);border-radius:3px;color:var(--cyan);
  font-family:var(--mono);font-size:12px;padding:10px 11px;letter-spacing:1.5px
}
input[type=text]:focus{outline:none;border-color:var(--cyan)}
.row{display:flex;gap:10px;margin-top:20px;flex-wrap:wrap}
.row button{flex:1 1 auto;padding:13px}
.big{background:linear-gradient(180deg,#0f4a34,#0a2e21);border-color:var(--neon-d);color:var(--neon);font-size:13px;font-weight:700}
.keys{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:8px;margin-top:14px}
.key{border:1px solid var(--line);border-radius:4px;padding:10px;background:rgba(8,15,23,.6)}
.key b{display:block;font-family:var(--mono);font-size:9px;letter-spacing:1.5px;color:var(--cyan);margin-bottom:4px}
.key span{font-size:11.5px;color:var(--dim);line-height:1.5}
.scoreline{display:flex;justify-content:space-between;padding:9px 0;border-bottom:1px solid var(--line);font-size:12.5px;color:var(--dim)}
.scoreline b{font-family:var(--mono);color:var(--ink);font-size:13px}
.scoreline.tot b{color:var(--neon);font-size:19px}
.rank{font-family:var(--mono);font-size:26px;color:var(--amber);letter-spacing:1px;margin-top:6px}

/* toast */
#toast{position:fixed;left:50%;top:64px;transform:translateX(-50%) translateY(-16px);z-index:75;
  background:rgba(9,17,26,.96);border:1px solid var(--line);border-left:3px solid var(--amber);
  padding:10px 16px;border-radius:3px;font-size:12.5px;color:var(--ink);opacity:0;transition:.25s;pointer-events:none;max-width:88vw}
#toast.on{opacity:1;transform:translateX(-50%) translateY(0)}

/* score popup */
.pop{position:fixed;z-index:76;font-family:var(--mono);font-size:16px;font-weight:700;color:var(--neon);
  pointer-events:none;text-shadow:0 0 14px rgba(38,255,156,.6);animation:popUp 1s ease-out forwards}
@keyframes popUp{0%{opacity:0;transform:translateY(6px) scale(.85)}18%{opacity:1;transform:translateY(-4px) scale(1.08)}100%{opacity:0;transform:translateY(-46px) scale(1)}}

@media (max-width:900px){
  .stage{grid-template-columns:1fr;grid-template-rows:minmax(230px,38vh) minmax(0,1fr);padding:8px;gap:8px}
  .stats .chip:nth-child(n+5){display:none}
  .brief{max-height:60%}
}
@media (prefers-reduced-motion:reduce){*{animation-duration:.01ms!important;transition-duration:.01ms!important}}
