/* ── Theme Variables ──────────────────────────────────────── */
:root {
  --bg:          #ffffff;
  --bg2:         #ffffff;
  --bg3:         #e8e8e8;
  --panel-bg:    #ffffff;
  --panel-head:  #e0e0e0;
  --border:      #cccccc;
  --border2:     #aaaaaa;
  --ro-item-border: #aaaaaa;
  --thumb-border:   #000000;
  --thumb-gap:      #ffffff;
  --text:        #222222;
  --text2:       #555555;
  --text3:       #888888;
  --accent:      #1a6ec0;
  --accent2:     #1558a0;
  --orange:      #e07800;
  --red:         #cc3300;
  --green:       #228833;
  --btn-bg:      #e0e0e0;
  --btn-border:  #aaaaaa;
  --btn-text:    #222222;
  --input-bg:    #ffffff;
  --shadow:      rgba(0,0,0,0.18);
  --canvas-bg:   #ffffff;
  --queue-info:  #d06000;
}
body.dark {
  --bg:          #0e0f11;
  --bg2:         #151618;
  --bg3:         #1c1e21;
  --panel-bg:    #1a1c1f;
  --panel-head:  #252830;
  --border:      #2a2d32;
  --border2:     #3a3d44;
  --ro-item-border: #ffffff;
  --thumb-border:   #bbbbbb;
  --thumb-gap:      #000000;
  --text:        #d4d8e0;
  --text2:       #8a90a0;
  --text3:       #555a66;
  --accent:      #3d8bff;
  --accent2:     #1a5fc0;
  --orange:      #f39c12;
  --red:         #e74c3c;
  --green:       #2ecc71;
  --btn-bg:      #252830;
  --btn-border:  #3a3d44;
  --btn-text:    #d4d8e0;
  --input-bg:    #1c1e21;
  --shadow:      rgba(0,0,0,0.5);
  --canvas-bg:   #111214;
  --queue-info:  #e8c020;
}

*,*::before,*::after { box-sizing:border-box; margin:0; padding:0; }
html,body { height:100%; overflow:hidden; background:var(--bg); color:var(--text);
  font-family:Arial,sans-serif; font-size:13px; line-height:1.4; }

/* ── App Shell ────────────────────────────────────────────── */
#app { display:flex; flex-direction:column; height:100vh; }

/* ── Header ───────────────────────────────────────────────── */
#header {
  display:flex; align-items:center; padding:0 12px; height:38px; flex-shrink:0;
  background:var(--bg2); border-bottom:1px solid var(--border); gap:8px;
}
#hamburger { font-size:18px; cursor:pointer; color:var(--text2); padding:4px 2px; }
#module-select {
  padding:3px 8px; border:1px solid var(--border2); border-radius:3px;
  background:var(--input-bg); color:var(--text); font-size:12px; cursor:pointer;
}
#header-title { flex:1; text-align:center; font-size:17px; font-weight:bold; color:var(--accent); }
#header-right { display:flex; align-items:center; gap:10px; }
#theme-btn {
  padding:2px 10px; border:1px solid var(--border2); border-radius:3px;
  background:var(--btn-bg); color:var(--btn-text); cursor:pointer; font-size:11px;
}
#logout-link { color:var(--accent); font-size:12px; cursor:pointer; }

/* ── Main ─────────────────────────────────────────────────── */
#main { display:flex; flex:1; overflow:hidden; }

/* ── Left Panel ───────────────────────────────────────────── */
#left-panel {
  width:305px; flex-shrink:0; background:var(--bg);
  border-right:1px solid var(--border);
  overflow-y:auto; padding:6px;
  display:flex; flex-direction:column; gap:5px;
}

/* Box panels */
.lp-box { background:var(--panel-bg); border:1px solid var(--border2); border-radius:3px; }
.lp-head {
  background:var(--panel-head); padding:5px 10px;
  font-weight:bold; font-size:13px;
  border-bottom:1px solid var(--border);
  border-radius:3px 3px 0 0;
}
.lp-body { padding:8px 10px; }

/* Selector rows */
.ss-row { display:flex; align-items:center; gap:5px; margin-bottom:4px; }
.ss-row > label { width:58px; flex-shrink:0; font-size:12px; color:var(--text2); }
.ss-row select {
  flex:1; min-width:0; max-width:100%;
  padding:2px 4px; border:1px solid var(--border2); border-radius:2px;
  background:var(--input-bg); color:var(--text); font-size:12px;
  /* Long channel / playlist / program names would otherwise widen
     the <select> beyond its row, pushing the popup off-panel. */
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.ss-row select option {
  /* Inside the dropdown popup itself; same intent — names that exceed
     the column width get cut off rather than expanding the popup. */
  max-width: 285px;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ss-row .wl { font-size:11px; color:var(--accent); cursor:pointer; white-space:nowrap; }
.ss-acts { display:flex; align-items:center; gap:8px; padding-left:63px; margin-bottom:4px; }
.ss-lnk { font-size:11px; color:var(--accent); cursor:pointer; }
.ss-lnk.red { color:var(--red); }
.ss-lnk.orange { color:var(--orange); font-size:15px; line-height:1; }

/* Slide control rows */
.sc-row { display:flex; align-items:center; gap:5px; margin-bottom:4px; }
.sc-row > label { width:100px; flex-shrink:0; font-size:12px; color:var(--text2); }
.sc-row input[type=text], .sc-row input[type=number] {
  flex:1; padding:2px 5px; border:1px solid var(--border2); border-radius:2px;
  background:var(--input-bg); color:var(--text); font-size:12px;
}
.sc-row input[type=color] {
  width:52px; height:22px; padding:1px 2px; border:1px solid var(--border2);
  border-radius:2px; cursor:pointer; background:var(--input-bg);
}
.sc-row input[type=range] { flex:1; cursor:pointer; accent-color:var(--accent); }
.sc-row select {
  flex:1; padding:2px 4px; border:1px solid var(--border2); border-radius:2px;
  background:var(--input-bg); color:var(--text); font-size:12px; outline:none;
}
.sc-row select:focus { border-color:var(--accent); }
.sc-row .unit { font-size:11px; color:var(--text3); white-space:nowrap; }
.sc-row .sc-lnk { font-size:11px; color:var(--accent); cursor:pointer; }
.save-btn {
  background:#1a6ec0; color:#fff; border:none; border-radius:3px;
  padding:4px 14px; font-size:13px; font-weight:bold; cursor:pointer; flex-shrink:0;
  transition:transform .5s cubic-bezier(.2,1,.3,1);
}
.save-btn:active:not(:disabled) { transform:scale(0.88); transition:transform .06s ease-in; }
.save-btn:hover { background:#1558a0; }
.sub-links { display:flex; gap:12px; margin-top:2px; }
.sub-lnk { font-size:11px; color:var(--accent); cursor:pointer; }
.sub-lnk.red { color:var(--red); }

/* Add Component rows */
.ac-row { display:flex; align-items:center; gap:6px; margin-bottom:5px; flex-wrap:wrap; }
.ac-row > label { width:96px; flex-shrink:0; font-size:12px; color:var(--text2); }
/* Icon used inside a label (legacy, kept for possible reuse). */
.ac-ico { width:14px; height:14px; flex-shrink:0; color:var(--text3); }
/* Icon-button: accent-colored, click target for adding a component. */
.ac-ico-btn {
  width:22px; height:22px; flex-shrink:0;
  color:var(--accent); cursor:pointer;
  padding:1px; border-radius:4px;
  transition:transform .15s ease, filter .15s ease, background .15s ease;
}
.ac-ico-btn:hover { filter:brightness(1.35); transform:scale(1.15); }
.ac-ico-btn:active { transform:scale(0.88); transition:transform .06s ease-in; }
.sc-row .ac-ico-btn { width:20px; height:20px; }
/* Shape-picker icon button used in the Shape component editor panel. */
.sh-btn {
  width:100%; height:34px; padding:4px; cursor:pointer; box-sizing:border-box;
  border:1px solid var(--border); border-radius:3px;
  background:#1a1a1a; color:var(--text2);
  transition:border-color .12s, background .12s, color .12s;
}
.sh-btn:hover { border-color:var(--accent); color:var(--text); }
.sh-btn.selected { border-color:var(--accent); background:var(--accent); color:#fff; }
.ac-btn {
  padding:1px 10px; border:1px solid var(--border2); border-radius:2px;
  background:var(--btn-bg); color:var(--btn-text); cursor:pointer; font-size:12px;
  transition:transform .5s cubic-bezier(.2,1,.3,1);
}
.ac-btn:active:not(:disabled) { transform:scale(0.88); transition:transform .06s ease-in; }
.ac-btn:hover { filter:brightness(0.92); }
/* Source-picker selected state (Choose File / Select / AIGen in the image
   editor). Stays highlighted to reflect comp.data.source_type. */
.e-src-btn.selected {
  background: var(--accent); color:#fff; border-color: var(--accent);
}
.e-src-btn.selected:hover { filter:brightness(1.05); }
.ac-btn:disabled { opacity:1; cursor:default; filter:none; background:var(--bg3) !important; color:var(--text3) !important; border-color:var(--border) !important; }
.ac-lnk { font-size:11px; color:var(--accent); cursor:pointer; }
.ac-url {
  flex:1; padding:2px 5px; border:1px solid var(--border2); border-radius:2px;
  background:var(--input-bg); color:var(--text); font-size:11px; min-width:0;
}

/* ── Center ───────────────────────────────────────────────── */
#center { flex:1; display:flex; flex-direction:column; overflow:hidden; }

/* Thumbnails */
#thumb-bar {
  display:flex; align-items:flex-start; gap:5px; padding:5px 8px;
  background:var(--bg2); border-bottom:1px solid var(--border);
  flex-shrink:0;
}
#thumb-label {
  font-size:13px; font-weight:bold; color:var(--accent);
  writing-mode:vertical-rl; transform:rotate(180deg);
  white-space:nowrap; flex-shrink:0; margin-right:3px; align-self:center;
}
.thumb-item {
  width:88px; flex-shrink:0; cursor:grab;
  display:flex; flex-direction:column; align-items:center; gap:3px;
  transition:opacity .15s;
}
.thumb-item.dragging { opacity:.35; cursor:grabbing; }
.thumb-img {
  width:88px; height:55px;
  border:none; border-radius:6px;
  box-shadow: 0 0 0 2px var(--thumb-gap), 0 0 0 4px var(--thumb-border);
  overflow:hidden; position:relative; flex-shrink:0;
  background:#000;
}
.thumb-item.drag-over .thumb-img { box-shadow: 0 0 0 2px var(--thumb-gap), 0 0 0 4px var(--accent); }
.thumb-item:hover .thumb-img    { box-shadow: 0 0 0 2px var(--thumb-gap), 0 0 0 4px var(--accent); }
.thumb-item.selected .thumb-img { box-shadow: 0 0 0 2px var(--thumb-gap), 0 0 0 4px #9933cc; }
.thumb-item.paused .thumb-img   { box-shadow: 0 0 0 2px var(--thumb-gap), 0 0 0 4px #cc0000; }
.thumb-label-small {
  font-size:9px; color:var(--text2);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  max-width:88px; text-align:center;
}

/* Candidate bar — accumulates across generations, so cap the height
   and let it scroll vertically when it overflows rather than pushing
   the canvas down. ~3 rows of thumbnails fits in 280px. */
#candidate-bar { display:none; flex-shrink:0; background:var(--bg2); border-bottom:1px solid var(--border); padding:6px 10px; max-height:280px; overflow-y:auto; }
#candidate-bar-inner { display:flex; align-items:center; gap:8px; flex-wrap:wrap; min-height:96px; }
.ai-cand-item { position:relative; flex-shrink:0; border:2px solid var(--border2); border-radius:5px; overflow:hidden; cursor:pointer; background:var(--bg3); transition:border-color .15s; }
.ai-cand-item:hover { border-color:var(--accent); }
.ai-cand-item.dragging { opacity:.35; }
.ai-cand-item img { display:block; width:100%; height:100%; object-fit:contain; }
.ai-cand-placeholder { display:flex; align-items:center; justify-content:center; flex-direction:column; gap:3px; color:var(--text2); font-size:11px; width:100%; height:100%; }
.ai-cand-close { position:absolute; top:3px; right:3px; background:rgba(0,0,0,.65); color:#fff; border:none; border-radius:50%; width:18px; height:18px; font-size:12px; line-height:1; cursor:pointer; display:flex; align-items:center; justify-content:center; z-index:2; padding:0; }
.ai-cand-close:hover { background:rgba(180,0,0,.9); }
.ai-cand-item.placed { border-color:#2a6; }
#cand-remove-all { font-size:11px; padding:4px 10px; border:1px solid var(--border2); border-radius:3px; background:var(--bg3); color:var(--text2); cursor:pointer; white-space:nowrap; flex-shrink:0; align-self:center; }
#cand-remove-all:hover { border-color:var(--accent); color:var(--text); }
.cand-hint {
  flex: 0 1 auto;
  font-size: 11px;
  color: var(--text2);
  padding: 0 8px;
  font-style: italic;
  align-self: center;
}
#canvas-stage.cand-drop-target { box-shadow:0 0 0 calc(4px * var(--inv-zoom, 1)) var(--accent), 0 0 30px 8px rgba(0,0,0,.7); }

/* Canvas scroll */
#canvas-scroll {
  flex:1; overflow:auto; background:var(--canvas-bg);
  padding:20px 300px 300px 20px; position:relative;
}
#canvas-label {
  position:absolute; top:5px; left:8px;
  font-size:13px; font-weight:bold; color:var(--accent);
  pointer-events:none;
}
#canvas-stage {
  --inv-zoom:1;
  position:relative; border:calc(1px * var(--inv-zoom)) solid #cc0000;
  background:#ffffff; transform-origin:top left;
  overflow:visible;
}
#canvas-empty {
  position:absolute; inset:0; display:flex; align-items:center;
  justify-content:center; flex-direction:column; gap:10px;
  color:var(--text3); font-size:14px; background:var(--canvas-bg);
  pointer-events:none;
}

/* ── Text marquee ────────────────────────────────────────── */
@keyframes marquee-rtl { from{transform:translateX(100%)} to{transform:translateX(-100%)} }
@keyframes marquee-ltr { from{transform:translateX(-100%)} to{transform:translateX(100%)} }

/* ── Text animations (Phase 1: Text component kinetic effects) ── */
@keyframes tx-fade-in      { from{opacity:0} to{opacity:1} }
@keyframes tx-slide-left   { from{transform:translateX(-120%);opacity:0} to{transform:translateX(0);opacity:1} }
@keyframes tx-slide-right  { from{transform:translateX(120%);opacity:0}  to{transform:translateX(0);opacity:1} }
@keyframes tx-slide-top    { from{transform:translateY(-120%);opacity:0} to{transform:translateY(0);opacity:1} }
@keyframes tx-slide-bottom { from{transform:translateY(120%);opacity:0}  to{transform:translateY(0);opacity:1} }
@keyframes tx-pulse        { 0%,100%{transform:scale(1);filter:brightness(1)} 50%{transform:scale(1.05);filter:brightness(1.25)} }
@keyframes tx-type-letter  { 0%{opacity:0} 49.99%{opacity:0} 50%{opacity:1} 100%{opacity:1} }
@keyframes tx-pop-letter   { 0%{transform:scale(0);opacity:0} 60%{transform:scale(1.25);opacity:1} 100%{transform:scale(1);opacity:1} }
.tx-letter { display:inline-block; white-space:pre; }

/* ── Canvas components ────────────────────────────────────── */
.cc { position:absolute; cursor:move; box-sizing:border-box; user-select:none; }
/* Alt/Option held → canvas is in pass-through mode: components are not
   draggable, so the cursor shows "pointer" instead of the 4-way move. */
body.alt-held .cc { cursor:pointer; }
.cc .cc-inner { pointer-events:none; width:100%; height:100%; overflow:hidden; }
.cc-outline {
  position:absolute; inset:calc(-1px * var(--inv-zoom, 1)); border:calc(2px * var(--inv-zoom, 1)) dashed rgba(100,100,255,.6);
  border-radius:2px; pointer-events:none; opacity:0;
}
.cc:hover .cc-outline { opacity:1; }
.cc.selected .cc-outline { opacity:1; border-style:solid; border-color:#3d8bff; }
/* Sync Images cross-zone peer — different colour from the active selection
   so the operator can tell at a glance which is the editing target and
   which is the synced counterpart. */
.cc.cc-sync-peer .cc-outline { border-color:#ff8c3d; border-style:dashed; }

/* ── Group bounding box (multi-select) ──────────────────── */
#group-box {
  position:absolute; box-sizing:border-box;
  border:calc(2px * var(--inv-zoom, 1)) dashed #ff8c3d;
  pointer-events:none;  /* interior transparent; clicks fall through */
  z-index:99990;
}
#group-box .gb-drag {
  position:absolute; pointer-events:auto; cursor:move; background:transparent;
}
/* Rim divs a bit wider than the visual border for easier grabbing */
#group-box .gb-drag.gb-top    { left:-8px; right:-8px; top:-8px; height:14px; }
#group-box .gb-drag.gb-bottom { left:-8px; right:-8px; bottom:-8px; height:14px; }
#group-box .gb-drag.gb-left   { top:-8px; bottom:-8px; left:-8px; width:14px; }
#group-box .gb-drag.gb-right  { top:-8px; bottom:-8px; right:-8px; width:14px; }
/* Corner resize handles — orange squares at each corner */
#group-box .gb-handle {
  position:absolute; pointer-events:auto;
  width:calc(12px * var(--inv-zoom, 1));
  height:calc(12px * var(--inv-zoom, 1));
  background:#ff8c3d;
  border:calc(1px * var(--inv-zoom, 1)) solid #fff;
  box-sizing:border-box; z-index:1;
}
#group-box .gb-handle.gb-nw { top:   calc(-6px * var(--inv-zoom,1)); left:  calc(-6px * var(--inv-zoom,1)); cursor:nwse-resize; }
#group-box .gb-handle.gb-ne { top:   calc(-6px * var(--inv-zoom,1)); right: calc(-6px * var(--inv-zoom,1)); cursor:nesw-resize; }
#group-box .gb-handle.gb-sw { bottom:calc(-6px * var(--inv-zoom,1)); left:  calc(-6px * var(--inv-zoom,1)); cursor:nesw-resize; }
#group-box .gb-handle.gb-se { bottom:calc(-6px * var(--inv-zoom,1)); right: calc(-6px * var(--inv-zoom,1)); cursor:nwse-resize; }
/* Group delete button — red X outside the top-right corner */
#group-box .gb-delete {
  position:absolute; pointer-events:auto;
  top:   calc(-10px * var(--inv-zoom,1));
  right: calc(-24px * var(--inv-zoom,1));
  width: calc(18px * var(--inv-zoom,1));
  height:calc(18px * var(--inv-zoom,1));
  border-radius:50%; background:#cc3333; color:#fff;
  border:calc(1px * var(--inv-zoom,1)) solid #fff;
  font-size:calc(11px * var(--inv-zoom,1));
  line-height:calc(16px * var(--inv-zoom,1));
  text-align:center; font-weight:bold;
  cursor:pointer; user-select:none; z-index:2;
  box-shadow:0 1px 3px rgba(0,0,0,.4);
}
#group-box .gb-delete:hover { background:#e04444; }
.rh {
  position:absolute; width:calc(14px * var(--inv-zoom, 1)); height:calc(14px * var(--inv-zoom, 1));
  background:#3d8bff; border:calc(2px * var(--inv-zoom, 1)) solid #fff; border-radius:3px;
  z-index:10; display:none; box-shadow:0 1px 3px rgba(0,0,0,.4);
}
.cc.selected .rh { display:block; }
.rh.nw{top:calc(-7px * var(--inv-zoom, 1));left:calc(-7px * var(--inv-zoom, 1));cursor:nw-resize}
.rh.ne{top:calc(-7px * var(--inv-zoom, 1));right:calc(-7px * var(--inv-zoom, 1));cursor:ne-resize}
.rh.sw{bottom:calc(-7px * var(--inv-zoom, 1));left:calc(-7px * var(--inv-zoom, 1));cursor:sw-resize}
.rh.se{bottom:calc(-7px * var(--inv-zoom, 1));right:calc(-7px * var(--inv-zoom, 1));cursor:se-resize}
.rh.rot{width:calc(18px * var(--inv-zoom, 1));height:calc(18px * var(--inv-zoom, 1));border-radius:50%;top:calc(-30px * var(--inv-zoom, 1));left:calc(50% - 9px * var(--inv-zoom, 1));cursor:grab;font-size:calc(10px * var(--inv-zoom, 1));line-height:1;align-items:center;justify-content:center;color:#fff;user-select:none;}
.cc.selected .rh.rot{display:flex;}
.rh.rot::after{content:'';position:absolute;top:100%;left:calc(50% - 1px * var(--inv-zoom, 1));width:calc(2px * var(--inv-zoom, 1));height:calc(10px * var(--inv-zoom, 1));background:#3d8bff;pointer-events:none;}
.cc-x {
  position:absolute; top:calc(-8px * var(--inv-zoom, 1)); right:calc(-8px * var(--inv-zoom, 1));
  width:calc(16px * var(--inv-zoom, 1)); height:calc(16px * var(--inv-zoom, 1)); background:#777; color:#fff;
  border-radius:50%; font-size:calc(10px * var(--inv-zoom, 1)); cursor:pointer;
  display:none; align-items:center; justify-content:center;
  z-index:20; border:calc(1px * var(--inv-zoom, 1)) solid #fff; line-height:1; box-shadow:0 1px 3px rgba(0,0,0,.4);
}
.cc.selected .cc-x { display:flex; }
.cc-x:hover { background:#cc3300 !important; }

/* ── Floating Component Editor ────────────────────────────── */
#comp-ed {
  position:absolute; top:10px; right:10px; width:281px;
  background:var(--panel-bg); border:1px solid var(--border2);
  border-radius:3px; box-shadow:0 4px 18px var(--shadow);
  display:none; z-index:200;
  max-height:calc(100vh - 120px); overflow-y:auto;
}
#comp-ed.open { display:block; }
#comp-ed.joined-below { border-radius:3px 3px 0 0; border-bottom:none; }
#lib-tray {
  position:fixed; top:80px; left:220px; width:220px;
  background:var(--panel-bg); border:1px solid var(--border2);
  border-radius:4px; box-shadow:0 4px 18px var(--shadow);
  display:none; z-index:300; max-height:calc(100vh - 120px);
  flex-direction:column; user-select:none;
}
#lib-tray.open { display:flex; }
#lib-tray-head {
  background:var(--panel-head); padding:5px 8px;
  font-size:12px; font-weight:600; cursor:move;
  display:flex; align-items:center; justify-content:space-between;
  border-bottom:1px solid var(--border); border-radius:4px 4px 0 0; flex-shrink:0;
}
#lib-tray-body {
  overflow-y:auto; padding:6px;
  display:grid; grid-template-columns:repeat(3,1fr); gap:5px;
}
#lib-tray-body img {
  width:100%; height:56px; object-fit:cover; display:block;
  border:2px solid transparent; border-radius:2px; cursor:grab;
  box-sizing:border-box;
}
#lib-tray-body img:hover { border-color:var(--accent); }
#lib-tray-body img[draggable]:active { cursor:grabbing; }
.grid-drop-over { outline:3px solid var(--accent) !important; outline-offset:-3px; }
#comp-ed-head {
  background:var(--panel-head); padding:5px 8px;
  font-weight:bold; font-size:13px;
  display:flex; align-items:center; justify-content:space-between;
  border-bottom:1px solid var(--border);
  cursor:move; user-select:none; border-radius:3px 3px 0 0;
}
#comp-ed-head button {
  width:17px; height:17px; background:#888; color:#fff;
  border:none; border-radius:2px; cursor:pointer; font-size:11px;
  display:flex; align-items:center; justify-content:center; padding:0;
}
#comp-ed-head button:hover { background:#cc3300; }
#comp-ed-body { padding:8px 10px; overflow-x:hidden; }

/* Editor field rows */
.er { display:flex; align-items:center; gap:5px; margin-bottom:4px; }
.er > label { width:105px; flex-shrink:0; font-size:12px; color:var(--text2); }
.er input[type=text],.er input[type=number],.er select,.er textarea {
  flex:1; padding:2px 4px; border:1px solid var(--border2); border-radius:2px;
  background:var(--input-bg); color:var(--text); font-size:12px; outline:none;
}
.er input:focus,.er select:focus,.er textarea:focus { border-color:var(--accent); }
.er input[type=color] { width:38px; height:22px; padding:1px; cursor:pointer;
  border:1px solid var(--border2); border-radius:2px; background:var(--input-bg); }
.er input[type=range] { flex:1; cursor:pointer; accent-color:var(--accent); }
.er input[type=checkbox] { width:13px; height:13px; cursor:pointer; flex-shrink:0; }
.er .unit { font-size:11px; color:var(--text3); white-space:nowrap; min-width:24px; }
.er textarea { resize:vertical; min-height:50px; flex:none; width:100%; }
.er-full { flex-direction:column; align-items:flex-start; }
.er-full > label { width:auto; margin-bottom:2px; }
/* Custom font picker */
.fp-wrap { position:relative; flex:1; }
.fp-trigger { display:flex; align-items:center; justify-content:space-between; padding:2px 6px;
  border:1px solid var(--border2); border-radius:2px; background:var(--input-bg);
  color:var(--text); cursor:pointer; font-size:14px; user-select:none; }
.fp-trigger:hover { border-color:var(--accent); }
.fp-list { position:fixed; background:var(--bg2); border:1px solid var(--border2);
  border-radius:3px; z-index:99999; max-height:260px; overflow-y:auto;
  box-shadow:0 4px 12px rgba(0,0,0,.4); display:none; min-width:180px; }
.fp-list.open { display:block; }
.fp-item { padding:5px 10px; cursor:pointer; font-size:15px; white-space:nowrap; }
.fp-item:hover { background:var(--hover); }
.fp-item.fp-sel { background:var(--accent); color:#fff; }
.fp-sep { padding:3px 8px; font-size:10px; color:var(--text3); font-style:italic;
  border-top:1px solid var(--border2); margin-top:2px; pointer-events:none; }
.er-rg { display:flex; align-items:baseline; margin-bottom:5px; }
.er-rg > label { width:105px; flex-shrink:0; font-size:12px; color:var(--text2); }
.er-rg-opts { display:flex; align-items:center; gap:6px; flex-wrap:nowrap; }
.ro { display:flex; align-items:center; gap:3px; font-size:12px; color:var(--text2); cursor:pointer; white-space:nowrap; }
.ro input { cursor:pointer; }
.ed-sec { border-top:1px solid var(--border); margin-top:6px; padding-top:5px; }
.ed-sec-title { font-size:10px; font-weight:bold; text-transform:uppercase;
  letter-spacing:.07em; color:var(--text3); margin-bottom:4px; }
.ed-del { width:100%; padding:5px; margin-top:8px; border:none; border-radius:3px; transition:transform .5s cubic-bezier(.2,1,.3,1);
  font-size:12px; font-weight:bold; cursor:pointer; }
.ed-del.blue { background:#1a6ec0; color:#fff; }
.ed-del.red { background:#cc3300; color:#fff; }
.ed-del:hover { opacity:.85; }
.ed-del:active:not(:disabled) { transform:scale(0.88); transition:transform .06s ease-in; }
.ed-del:disabled { background:var(--bg3); color:var(--text3); cursor:default; opacity:1; }
.ed-lnk { font-size:11px; color:var(--accent); cursor:pointer; display:inline-block; margin-top:3px; }
/* Brief confirmation state applied by saveCompDefault — green text with a
   short scale pulse, auto-cleared ~1.4s later. */
.ed-lnk.ed-lnk-saved {
  color:#4cd964; cursor:default; font-weight:600;
  animation: ed-lnk-saved-pulse .45s ease-out;
}
@keyframes ed-lnk-saved-pulse {
  0%   { transform:scale(1);    opacity:.6; }
  40%  { transform:scale(1.18); opacity:1;  }
  100% { transform:scale(1);    opacity:1;  }
}

/* ── Modal ────────────────────────────────────────────────── */
#modal-ov {
  position:fixed; inset:0; background:rgba(0,0,0,.45);
  z-index:1000; display:none; align-items:center; justify-content:center;
}
#modal-ov.open { display:flex; }

/* ── Touch Up Modal ──────────────────────────────────────── */
#tu-modal { position:fixed; inset:0; background:rgba(0,0,0,.65); z-index:2000; display:none; align-items:center; justify-content:center; }
#tu-modal.open { display:flex; }
#tu-modal-inner { background:var(--panel-bg); border:1px solid var(--border2); border-radius:6px; box-shadow:0 8px 32px rgba(0,0,0,.7); display:flex; flex-direction:column; max-width:92vw; max-height:92vh; min-width:400px; }
#tu-header { display:flex; align-items:center; justify-content:space-between; padding:8px 12px; border-bottom:1px solid var(--border); flex-shrink:0; }
#tu-header span { font-weight:600; font-size:13px; color:var(--text); }
#tu-canvas-wrap { overflow:auto; flex:1; position:relative; background:repeating-conic-gradient(#666 0% 25%,#999 0% 50%) 0 0/16px 16px; }
#tu-bg-canvas { display:block; visibility:hidden; }
#tu-overlay-canvas { position:absolute; top:0; left:0; cursor:crosshair; touch-action:none; }
#tu-status-bar { padding:5px 12px; font-size:11px; color:var(--text3); border-top:1px solid var(--border); flex-shrink:0; min-height:24px; }
#tu-action-bar { display:none; align-items:center; gap:8px; padding:7px 12px; border-top:1px solid var(--border); flex-shrink:0; flex-wrap:wrap; }
#tu-action-bar.visible { display:flex; }
#tu-action-bar label { font-size:11px; color:var(--text2); white-space:nowrap; }
#tu-action-bar input[type=color] { width:28px; height:22px; padding:0; border:1px solid var(--border2); border-radius:2px; cursor:pointer; }
#tu-action-bar button:disabled { opacity:0.4; cursor:default; pointer-events:none; }
/* ── AI Slide Designer ───────────────────────────────────── */
#ai-design-modal { position:fixed; inset:0; background:rgba(0,0,0,.65); z-index:2000; display:none; align-items:center; justify-content:center; }
#ai-design-modal.open { display:flex; }
#ai-design-inner { background:var(--panel-bg); border:1px solid var(--border2); border-radius:6px; box-shadow:0 8px 32px rgba(0,0,0,.7); width:420px; max-width:94vw; display:flex; flex-direction:column; }
#ai-design-head { display:flex; align-items:center; justify-content:space-between; padding:8px 12px; border-bottom:1px solid var(--border); flex-shrink:0; }
#ai-design-head span { font-weight:bold; font-size:13px; }
#ai-design-body { padding:14px 14px 10px; }
#ai-design-foot { display:flex; align-items:center; justify-content:flex-end; gap:8px; padding:8px 12px; border-top:1px solid var(--border); }
#ad-style-input { width:100%; box-sizing:border-box; padding:6px 8px; border:1px solid var(--border2); border-radius:3px; background:var(--input-bg); color:var(--text); font-size:12px; font-family:inherit; }
#ad-status-line { font-size:11px; color:var(--text3); min-height:18px; margin-top:8px; }
#ad-result-bar { display:none; margin-top:10px; padding:8px 10px; background:var(--accent-dim,rgba(100,50,180,.12)); border:1px solid var(--accent); border-radius:4px; font-size:11px; color:var(--text2); }
#ad-result-bar.visible { display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
#ad-result-bar button { font-size:11px; padding:3px 9px; }
/* ── Draw Modal ───────────────────────────────────────────── */
#draw-modal {
  position:fixed; inset:0; background:rgba(0,0,0,.65);
  z-index:2000; display:none; align-items:center; justify-content:center;
}
#draw-modal.open { display:flex; }
#draw-modal-inner {
  background:var(--panel-bg); border:1px solid var(--border2);
  border-radius:6px; box-shadow:0 8px 32px rgba(0,0,0,.7);
  display:flex; flex-direction:column;
  /* Default sizing when no persisted box; JS may override with inline
     width/height/left/top once user drags or resizes. */
  width:85vw; height:82vh; max-width:96vw; max-height:96vh;
  min-width:360px; min-height:260px;
  position:relative; /* for #draw-resize-handle positioning */
}
#draw-modal.floating { align-items:flex-start; justify-content:flex-start; }
#draw-modal.floating #draw-modal-inner { position:absolute; }
#draw-resize-handle {
  position:absolute; right:0; bottom:0; width:16px; height:16px;
  cursor:nwse-resize; z-index:5;
  background:
    linear-gradient(135deg, transparent 0 45%, var(--text3) 46% 52%, transparent 53% 62%, var(--text3) 63% 70%, transparent 71%);
}
#draw-viewport {
  position:relative; flex-shrink:0;
}
#draw-backdrop {
  position:absolute; inset:0; width:100%; height:100%;
  object-fit:fill; pointer-events:none; z-index:0;
  display:none; /* shown once the snapshot loads */
  /* Keep pixel art crisp when zoomed in */
  image-rendering:auto;
}
#draw-canvas { position:relative; z-index:1; }
#draw-canvas-wrap {
  overflow:auto; flex:1; background:#444;
  display:flex; align-items:safe center; justify-content:safe center;
  padding:12px;
}
#draw-toolbar {
  display:flex; align-items:center; gap:8px; padding:7px 10px;
  border-bottom:1px solid var(--border); flex-wrap:wrap; flex-shrink:0;
  cursor:move; user-select:none;
}
#draw-toolbar input, #draw-toolbar button, #draw-toolbar label,
#draw-toolbar select, #draw-toolbar .dm-color-swatch { cursor:default; }
#draw-toolbar input[type=checkbox] { cursor:pointer; }
#draw-toolbar button { cursor:pointer; }
#draw-toolbar .dm-color-swatch { cursor:pointer; }
#draw-toolbar input[type=range] { cursor:pointer; }
#draw-toolbar label { font-size:11px; color:var(--text2); white-space:nowrap; }
#draw-toolbar input[type=range] { width:70px; cursor:pointer; accent-color:var(--accent); }
.dm-color-swatch { display:inline-block; width:32px; height:22px; border:1px solid var(--border2); border-radius:2px; cursor:pointer; flex-shrink:0; vertical-align:middle; }
.dm-color-swatch:hover { border-color:var(--accent); }
#dm-color-pop {
  position:fixed; z-index:3100; display:none;
  background:var(--panel-bg); border:1px solid var(--border2);
  border-radius:5px; box-shadow:0 6px 20px rgba(0,0,0,.6); padding:8px;
  min-width:120px;
}
#dm-color-pop-head { display:flex; align-items:center; justify-content:space-between; margin-bottom:6px; gap:8px; }
#dm-color-pop-head span { font-size:11px; color:var(--text2); white-space:nowrap; }
#dm-color-pop input[type=color] { width:100px; height:72px; padding:0; border:1px solid var(--border2); border-radius:3px; cursor:pointer; display:block; }
#draw-brush-preview {
  width:24px; height:24px; border-radius:50%;
  border:1px solid var(--border2); flex-shrink:0;
  display:flex; align-items:center; justify-content:center;
  background:transparent;
}
#draw-canvas { display:block; cursor:crosshair; touch-action:none; }
/* Region Select overlay inside #draw-viewport — positioned in canvas-CSS pixels. */
#draw-sel-overlay {
  position:absolute; box-sizing:border-box;
  border:1px dashed #ff8c3d;
  background:rgba(255,140,61,0.12);
  pointer-events:auto; cursor:move;
  touch-action:none; z-index:2;
}
#draw-footer {
  display:flex; align-items:center; justify-content:space-between;
  padding:7px 10px; border-top:1px solid var(--border); flex-shrink:0; gap:6px;
}
#draw-footer .draw-mode-btns { display:flex; gap:4px; }
.draw-mode-btn { padding:3px 9px; font-size:11px; border-radius:3px; border:1px solid var(--border2); background:var(--btn-bg); color:var(--btn-text); cursor:pointer; }
.draw-mode-btn.active { background:var(--accent); color:#fff; border-color:var(--accent); }
.modal {
  background:var(--panel-bg); border:1px solid var(--border2);
  border-radius:4px; padding:16px; min-width:320px; max-width:460px;
  box-shadow:0 8px 32px var(--shadow);
}
.modal h3 { font-size:14px; font-weight:bold; margin-bottom:10px; }
.modal-row { display:flex; align-items:center; gap:8px; margin-bottom:7px; }
.modal-row > label { width:90px; flex-shrink:0; font-size:12px; }
.modal-row input[type=range] { flex:1; padding:0; cursor:pointer; accent-color:var(--accent); }
.modal-row input,.modal-row select {
  flex:1; padding:4px 6px; border:1px solid var(--border2); border-radius:2px;
  background:var(--input-bg); color:var(--text); font-size:12px;
}
.modal-footer { display:flex; justify-content:flex-end; gap:8px; margin-top:12px; }
.mbtn {
  padding:5px 16px; border:1px solid var(--border2); border-radius:3px;
  background:var(--btn-bg); color:var(--btn-text); cursor:pointer; font-size:12px;
}
.mbtn.primary { background:#1a6ec0; color:#fff; border-color:#1a6ec0; font-weight:bold; }
.mbtn:hover { opacity:.85; }
.mbtn:disabled { opacity:.4; cursor:default; }

/* ── Status bar ───────────────────────────────────────────── */
#statusbar {
  height:21px; display:flex; align-items:center; padding:0 10px; gap:12px;
  background:var(--bg2); border-top:1px solid var(--border);
  font-size:10px; color:var(--text3); flex-shrink:0;
}
.sdot { width:6px; height:6px; border-radius:50%; background:#22cc55; display:inline-block; }
.sdot.red { background:#cc3300; }

::-webkit-scrollbar { width:5px; height:5px; }
::-webkit-scrollbar-track { background:transparent; }
::-webkit-scrollbar-thumb { background:var(--border2); border-radius:3px; }

/* ── AI Assistant Panel ───────────────────────────────────── */
#ai-panel {
  position:absolute; right:10px; width:320px;
  background:var(--panel-bg); border:1px solid var(--border2);
  border-radius:3px; box-shadow:0 4px 18px var(--shadow);
  display:none; z-index:199; overflow:visible;
}
#ai-panel.open { display:block; }

/* ── 3D Animation Panel — same shape as #ai-panel ───────────── */
#td3-panel {
  position:absolute; right:10px; width:320px;
  background:var(--panel-bg); border:1px solid var(--border2);
  border-radius:3px; box-shadow:0 4px 18px var(--shadow);
  display:none; z-index:199; overflow:visible;
}
#td3-panel.open { display:block; }
#td3-panel-head {
  background:var(--panel-head); padding:5px 8px;
  font-weight:bold; font-size:13px;
  display:flex; align-items:center; justify-content:space-between;
  border-bottom:1px solid var(--border);
  border-radius:3px 3px 0 0;
  cursor:move; user-select:none;
}
/* No max-height/overflow on the body — let the panel grow to fit
   content like #ai-panel does. The scrollbar that was appearing here
   was triggered by content barely exceeding 75vh even when the page
   had room to spare. */
#td3-panel-body { padding:6px 8px 8px; }
#ai-panel-head {
  background:var(--panel-head); padding:5px 8px;
  font-weight:bold; font-size:13px;
  display:flex; align-items:center; justify-content:space-between;
  border-bottom:1px solid var(--border);
  border-radius:3px 3px 0 0;
  cursor:move; user-select:none;
}
#ai-log {
  height:100px; overflow-y:auto; font-size:11px; line-height:1.5;
  padding:4px 2px; display:flex; flex-direction:column; gap:4px;
  border:1px solid var(--border); border-radius:3px; background:var(--bg2);
  box-sizing:border-box;
}
.ai-msg { padding:4px 7px; border-radius:4px; max-width:100%; word-break:break-word; }
.ai-msg.user { background:var(--accent); color:#fff; align-self:flex-end; }
.ai-msg.user.retry { opacity:0.65; font-style:italic; }
.ai-msg.assistant { background:var(--bg3); color:var(--text); align-self:flex-start; }
.ai-msg.thinking { color:var(--text3); font-style:italic; align-self:flex-start; }
#ai-input-row { display:flex; flex-direction:column; gap:4px; margin-top:6px; }
#ai-prompt-line { display:flex; gap:4px; align-items:flex-start; }
#ai-send-line { display:flex; gap:4px; flex-wrap:wrap; align-items:center; }
#ai-input {
  flex:1; padding:6px 8px; border:1px solid var(--border2); border-radius:3px;
  background:var(--input-bg); color:var(--text); font-size:12px; resize:vertical; min-height:124px;
}
#ai-input:focus { border-color:var(--accent); outline:none; }
#ai-send {
  padding:4px 10px; background:var(--accent); color:#fff; border:none;
  border-radius:3px; cursor:pointer; font-size:12px; flex-shrink:0;
  transition:transform .5s cubic-bezier(.2,1,.3,1);
}
#ai-send:active:not(:disabled) { transform:scale(0.88); transition:transform .06s ease-in; }
#ai-send:disabled { opacity:0.5; cursor:not-allowed; }
#ai-send:hover:not(:disabled) { background:var(--accent2); }
#ai-elab-btn {
  padding:4px 10px; background:transparent; color:var(--accent);
  border:1px solid var(--accent); border-radius:3px; cursor:pointer;
  font-size:12px; flex-shrink:0; transition:background .15s, color .15s;
}
#ai-elab-btn:hover:not(:disabled) { background:var(--accent); color:#fff; }
#ai-elab-btn:disabled { opacity:0.4; cursor:not-allowed; }
#ai-elab-btn.previewing { background:var(--accent); color:#fff; }
#ai-elab-revert:hover { color:var(--accent) !important; text-decoration:underline !important; }
#ai-elaborate-row, #ai-transparent-row, #ai-orient-row { display:flex; flex-wrap:nowrap; gap:10px; margin-top:5px; font-size:11px; color:var(--text2); white-space:nowrap; }
#ai-elaborate-row label, #ai-transparent-row label, #ai-orient-row label { cursor:pointer; user-select:none; display:flex; align-items:center; gap:4px; }
#ai-quality-row { display:flex; gap:12px; margin-top:5px; font-size:11px; color:var(--text3); }
#ai-quality-row label { cursor:pointer; user-select:none; display:flex; align-items:center; gap:4px; position:relative; }
#ai-quality-row label .tip {
  display:none; position:absolute; bottom:calc(100% + 5px); left:0;
  background:#222; color:#eee; font-size:10px; padding:5px 8px;
  border-radius:4px; white-space:nowrap; z-index:999;
  pointer-events:none; box-shadow:0 2px 6px rgba(0,0,0,0.4);
}
#ai-quality-row label:hover .tip { display:block; }
#ai-speed-row { display:flex; margin-top:4px; align-items:center; gap:6px; }
#ai-speed-row input[type=range] { flex:1; accent-color:#2a6; }
#ai-speed-row .spd-label { font-size:10px; color:var(--text2); white-space:nowrap; }
#ai-speed-row .spd-val { font-size:10px; color:#2a6; font-weight:600; min-width:58px; text-align:center; }
#ai-style-row { display:flex; flex-wrap:wrap; gap:4px; margin-top:5px; }
.ai-style-btn { font-size:10px; padding:2px 6px; border:1px solid var(--border2); border-radius:3px; background:var(--bg3); color:var(--text2); cursor:pointer; white-space:nowrap; }
.ai-style-btn:hover { border-color:var(--accent); color:var(--text); }
.ai-style-btn.active { background:var(--accent); color:#fff; border-color:var(--accent); }

/* ── AI Video Panel ─────────────────────────────────────── */
#ai-video-panel {
  position:absolute; right:10px; width:281px;
  background:var(--panel-bg); border:1px solid var(--border2);
  border-top:none;
  border-radius:0 0 3px 3px; box-shadow:0 4px 18px var(--shadow);
  display:none; z-index:199;
}
#ai-video-panel.open { display:block; }
#ai-video-panel-head {
  background:var(--panel-head); padding:5px 8px;
  font-weight:bold; font-size:13px;
  display:flex; align-items:center; justify-content:space-between;
  border-bottom:1px solid var(--border);
  border-top:1px solid var(--border);
  border-radius:0;
  user-select:none;
}
#ai-video-panel .lp-body { padding:8px; }
/* Video panel mode selector — three buttons at the top, same pattern as
   the Image panel's File / Select / AIGen source buttons. The .selected
   one gets the accent fill; only its matching #vid-content-<mode> block
   is shown via inline display. */
.vid-mode-btn-row { display:flex; gap:6px; margin-bottom:8px; }
.vid-mode-btn { flex:1; padding:6px 4px; font-size:11px; font-weight:600; }
.vid-mode-btn.selected {
  background: var(--accent); color:#fff; border-color: var(--accent);
}
.vid-mode-btn.selected:hover { filter:brightness(1.05); }
.vid-mode-content { margin-bottom:6px; }

/* ── Channel Management ──────────────────────────────────── */
#channel-mgmt { background:var(--bg); }
#cm-toolbar { display:flex; gap:8px; margin-bottom:12px; align-items:center; }
#cm-search {
  flex:1; max-width:300px; padding:5px 8px;
  border:1px solid var(--border2); border-radius:3px;
  background:var(--input-bg); color:var(--text); font-size:12px;
}
#cm-table { width:100%; border-collapse:collapse; font-size:13px; }
#cm-table th {
  text-align:left; padding:6px 10px;
  background:var(--panel-head); border-bottom:2px solid var(--border);
  font-size:12px; color:var(--text2); text-transform:uppercase; letter-spacing:.03em;
  position:sticky; top:0; z-index:1;
}
#cm-table td { padding:5px 10px; border-bottom:1px solid var(--border); }
#cm-table tr.cm-row:hover td { background:var(--bg3); }
#cm-table tr.cm-row { cursor:pointer; }
.cm-icon { margin-right:6px; vertical-align:-2px; }
.cm-lnk {
  color:var(--accent); cursor:pointer; font-size:12px; margin-right:8px;
  background:none; border:none; padding:0; font-family:inherit;
}
.cm-lnk:hover { text-decoration:underline; }
.cm-indent { display:inline-block; }
.cm-icon-wrap { cursor:default; display:inline-block; vertical-align:middle; }
.cm-icon-click { cursor:pointer; }
.cm-drag {
  cursor:grab; color:var(--text3); margin-right:6px; font-size:14px;
  user-select:none; vertical-align:middle;
}
.cm-drag:active { cursor:grabbing; }
.cm-row { position:relative; }
.cm-dragging td { opacity:0; }
.cm-drop-line::after {
  content:''; position:absolute; left:0; right:0; bottom:-2px;
  height:3px; background:var(--accent); z-index:2; pointer-events:none;
}
.cm-drop-child td { background:var(--accent); color:#fff; }

/* ── User Management ─────────────────────────────────────── */
#user-mgmt { background:var(--bg); }
#um-toolbar { display:flex; gap:8px; margin-bottom:12px; align-items:center; }
#um-search {
  flex:1; max-width:300px; padding:5px 8px;
  border:1px solid var(--border2); border-radius:3px;
  background:var(--input-bg); color:var(--text); font-size:12px;
}
#um-table { width:100%; border-collapse:collapse; font-size:13px; }
#um-table th {
  text-align:left; padding:6px 10px;
  background:var(--panel-head); border-bottom:2px solid var(--border);
  font-size:12px; color:var(--text2); text-transform:uppercase; letter-spacing:.03em;
  position:sticky; top:0; z-index:1;
}
#um-table td { padding:5px 10px; border-bottom:1px solid var(--border); }
#um-table tr.um-row:hover td { background:var(--bg3); }
#um-table tr.um-row { cursor:pointer; }
.um-lnk {
  color:var(--accent); cursor:pointer; font-size:12px; margin-right:8px;
  background:none; border:none; padding:0; font-family:inherit;
}
.um-lnk:hover { text-decoration:underline; }
.um-type { font-size:11px; padding:2px 6px; border-radius:3px; }
.um-type-user { background:var(--bg3); color:var(--text2); }
.um-type-admin { background:#2a5a8a; color:#fff; }
.um-type-superadmin { background:#8a2a5a; color:#fff; }

/* ── Playlist Scheduler ──────────────────────────────────── */
#scheduler { display:flex; background:var(--bg); }
#sch-left { flex:1; display:flex; flex-direction:column; overflow:hidden; border-right:1px solid var(--border); margin-right:8px; }
#sch-right { width:280px; flex-shrink:0; overflow-y:auto; background:var(--panel-bg); }
#sch-mini-cal { border-bottom:1px solid var(--border); padding:4px 8px 6px; }
#sch-mini-body span { padding:2px; cursor:pointer; border-radius:3px; }
#sch-mini-body span:hover { background:var(--bg3); }
#sch-mini-body span.mini-today { color:var(--orange); font-weight:bold; font-size:12px; }
#sch-mini-body span.mini-selected { background:rgba(255,220,40,0.5); color:var(--text); border-radius:3px; font-weight:bold; }
#sch-mini-body span.mini-other { color:var(--text3); }
#sch-right .ss-row { display:flex; align-items:center; gap:6px; margin-bottom:4px; font-size:12px; }
#sch-right .ss-row label { width:58px; flex-shrink:0; font-size:11px; color:var(--text2); }
#sch-right .ss-row select, #sch-right .ss-row input { flex:1; font-size:12px; padding:3px 5px; border:1px solid var(--border2); border-radius:3px; background:var(--bg2); color:var(--text); }
#sch-right input[type="number"], #sch-right input[type="date"] { background:var(--bg2); color:var(--text); border:1px solid var(--border); border-radius:3px; -webkit-appearance:none; appearance:none; padding:3px 5px; }

.sch-tsel { width:auto; flex:0 !important; font-size:12px; padding:3px 2px; border:1px solid var(--border2); border-radius:3px; background:var(--bg2); color:var(--text); }

/* Calendar nav */
#sch-cal-nav {
  display:flex; align-items:center; gap:6px; padding:8px 12px;
  background:var(--panel-head); border-bottom:1px solid var(--border); font-size:14px; font-weight:bold;
}
.sch-nav-btn {
  background:none; border:1px solid var(--border2); border-radius:3px;
  color:var(--text); cursor:pointer; font-size:16px; padding:0 6px; line-height:1.4;
}
.sch-nav-btn:hover { background:var(--bg3); }
.sch-view-btn {
  font-size:11px; padding:2px 8px; border:1px solid var(--border2); border-radius:3px;
  background:var(--btn-bg); color:var(--btn-text); cursor:pointer;
}
.sch-view-btn.active { background:var(--accent); color:#fff; border-color:var(--accent); }

/* Calendar head (day labels) */
#sch-cal-head {
  display:grid; grid-template-columns:repeat(7,1fr);
  background:var(--panel-head); border-bottom:1px solid var(--border);
  font-size:11px; color:var(--text2); text-transform:uppercase; text-align:center;
}
#sch-cal-head span { padding:4px; }

/* Month view */
#sch-cal-body { flex:1; overflow-y:auto; }
#sch-cal-body.sch-month {
  display:grid; grid-template-columns:repeat(7,1fr); grid-auto-rows:minmax(80px,1fr);
}
.sch-day-cell {
  border:1px solid var(--border); padding:2px 4px; font-size:11px; overflow-y:auto; cursor:pointer;
  position:relative; min-height:80px;
}
.sch-day-cell:hover { background:var(--bg3); }
.sch-day-num { font-weight:bold; font-size:12px; color:var(--text); margin-bottom:2px; }
.sch-day-other .sch-day-num { color:var(--text3); }
.sch-day-weekend { background:rgba(128,128,128,0.08); }
.sch-day-selected { background:rgba(255,220,40,0.18); }
.sch-day-today { }
.sch-day-today .sch-day-num { color:var(--orange); }
.sch-entry {
  font-size:10px; padding:1px 3px; margin:1px 0; border-radius:2px;
  background:transparent; color:var(--text); cursor:pointer; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.sch-entry:hover { background:var(--accent); color:#fff; }
.sch-entry:hover .sch-entry-time { color:#fff; }
.sch-entry.active { background:transparent; color:var(--red); font-weight:bold; }
.sch-entry-time { color:var(--accent); }
.sch-day-clash { background:rgba(255,60,60,0.15) !important; }

/* Week view */
#sch-cal-body.sch-week {
  display:grid; grid-template-columns:50px repeat(7,1fr);
  grid-template-rows:repeat(24,80px);
}
.sch-hour-label {
  font-size:10px; color:var(--text3); text-align:right; padding:2px 4px;
  border-bottom:1px solid var(--border); border-right:1px solid var(--border);
}
.sch-week-cell {
  border-bottom:1px solid var(--border); border-right:1px solid var(--border);
  position:relative; cursor:pointer; overflow:visible;
}
.sch-week-selected { background:rgba(255,220,40,0.18); }
.sch-week-weekend { background:rgba(128,128,128,0.08); }
.sch-week-cell:hover { background:var(--bg3); }
.sch-week-entries {
  position:absolute; left:0; right:0; top:0; bottom:0; overflow-y:auto; z-index:1;
}
.sch-week-entry {
  border-radius:2px;
  font-size:12px; padding:2px 4px; margin-bottom:1px;
  background:transparent; color:var(--text); cursor:pointer; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.sch-week-entry:hover { background:var(--accent); color:#fff; }
.sch-week-entry:hover .sch-entry-time { color:#fff; }
.sch-week-entry.active { color:var(--red); font-weight:bold; }
.sch-week-today { background:rgba(255,220,40,0.08); }

/* ── Interactive Tour ────────────────────────────────────── */
#tour-overlay {
  display:none; position:fixed; inset:0; z-index:9000;
  background:rgba(0,0,0,0.55); transition:opacity .2s;
}
.tour-spotlight {
  position:relative; z-index:9001 !important;
  box-shadow:0 0 0 4px var(--accent), 0 0 0 9999px rgba(0,0,0,0.55);
  border-radius:4px;
}
#tour-tooltip {
  display:none; position:fixed; z-index:9002;
  background:var(--panel-bg); border:1px solid var(--accent);
  border-radius:6px; padding:16px; box-shadow:0 4px 20px rgba(0,0,0,0.4);
  max-width:340px; font-size:13px; color:var(--text);
}
#tour-title {
  font-size:15px; font-weight:bold; color:var(--accent); margin-bottom:8px;
}
#tour-text {
  line-height:1.5; color:var(--text2); margin-bottom:12px;
}
#tour-footer {
  display:flex; align-items:center; justify-content:space-between;
}
#tour-step-info { font-size:11px; color:var(--text3); }
#tour-btns { display:flex; gap:6px; }
#tour-btns button {
  padding:4px 12px; border:1px solid var(--border2); border-radius:3px;
  background:var(--btn-bg); color:var(--btn-text); cursor:pointer; font-size:12px;
}
#tour-btns button:hover { background:var(--bg3); }
#tour-next { background:var(--accent) !important; color:#fff !important; border-color:var(--accent) !important; }
#tour-next:hover { opacity:0.9; }
#tour-btns button:disabled { opacity:0.4; cursor:default; }

/* ── Music Scheduler ──────────────────────────────────────
   Reuses the .sch-* class rules from the Playlist Scheduler.
   These aliases extend the ID-based layout rules to the
   parallel mus-* IDs so the two schedulers look identical. */
#music-scheduler { display:flex; background:var(--bg); }
#mus-left { flex:1; display:flex; flex-direction:column; overflow:hidden; border-right:1px solid var(--border); margin-right:8px; }
#mus-right { width:280px; flex-shrink:0; overflow-y:auto; background:var(--panel-bg); }
#mus-mini-cal { border-bottom:1px solid var(--border); padding:4px 8px 6px; }
#mus-mini-body span { padding:2px; cursor:pointer; border-radius:3px; }
#mus-mini-body span:hover { background:var(--bg3); }
#mus-mini-body span.mini-today { color:var(--orange); font-weight:bold; font-size:12px; }
#mus-mini-body span.mini-selected { background:rgba(255,220,40,0.5); color:var(--text); border-radius:3px; font-weight:bold; }
#mus-mini-body span.mini-other { color:var(--text3); }
#mus-right .ss-row { display:flex; align-items:center; gap:6px; margin-bottom:4px; font-size:12px; }
#mus-right .ss-row label { width:58px; flex-shrink:0; font-size:11px; color:var(--text2); }
#mus-right .ss-row select, #mus-right .ss-row input { flex:1; font-size:12px; padding:3px 5px; border:1px solid var(--border2); border-radius:3px; background:var(--bg2); color:var(--text); }
#mus-right input[type="number"], #mus-right input[type="date"] { background:var(--bg2); color:var(--text); border:1px solid var(--border); border-radius:3px; -webkit-appearance:none; appearance:none; padding:3px 5px; }
#mus-cal-nav {
  display:flex; align-items:center; gap:6px; padding:8px 12px;
  background:var(--panel-head); border-bottom:1px solid var(--border); font-size:14px; font-weight:bold;
}
#mus-cal-head {
  display:grid; grid-template-columns:repeat(7,1fr);
  background:var(--panel-head); border-bottom:1px solid var(--border);
  font-size:11px; color:var(--text2); text-transform:uppercase; text-align:center;
}
#mus-cal-head span { padding:4px; }
#mus-cal-body { flex:1; overflow-y:auto; }
#mus-cal-body.sch-month {
  display:grid; grid-template-columns:repeat(7,1fr); grid-auto-rows:minmax(80px,1fr);
}
#mus-cal-body.sch-week {
  display:grid; grid-template-columns:50px repeat(7,1fr);
  grid-template-rows:repeat(24,80px);
}
.mus-lib-row { /* modal row styling for audio library is inline; this hook exists for future tweaks */ }

/* ── Alerts Module ──────────────────────────────────────────────────────────── */
#alerts-module { display:flex; height:100%; }
#alt-left { padding:0; }
#alt-left .lp-box { border-bottom:1px solid var(--border); }
#alt-left .lp-head { padding:6px 10px; font-size:12px; font-weight:700; background:var(--bg3); color:var(--text2); border-bottom:1px solid var(--border); }
#alt-left .lp-body { padding:8px 10px; }
#alt-left .ss-row { display:flex; align-items:center; gap:6px; margin-bottom:4px; font-size:12px; }
#alt-left .ss-row label { width:58px; flex-shrink:0; font-size:11px; color:var(--text2); }
#alt-left .ss-row select, #alt-left .ss-row input[type="text"], #alt-left .ss-row input[type="number"] { flex:1; font-size:12px; padding:3px 5px; border:1px solid var(--border2); border-radius:3px; background:var(--bg2); color:var(--text); }
#alt-left .sc-row { display:flex; align-items:center; gap:6px; margin-bottom:4px; font-size:12px; }
#alt-left .sc-row label { width:auto; flex-shrink:0; font-size:11px; color:var(--text2); }
#alt-left .sc-row input[type="text"] { flex:1; font-size:12px; padding:3px 5px; border:1px solid var(--border2); border-radius:3px; background:var(--bg2); color:var(--text); }

/* Thumbnails */
.alt-thumb { width:80px; height:50px; border-radius:4px; cursor:pointer; flex-shrink:0; display:flex; align-items:flex-end; justify-content:center; border:2px solid transparent; overflow:hidden; position:relative; }
.alt-thumb.selected { border-color:var(--accent); }
.alt-thumb.active { box-shadow:0 0 0 2px var(--red); }
.alt-thumb:hover { opacity:.85; }

/* Canvas components */
.alt-comp { transition:none; }
.alt-comp.selected { outline:2px solid var(--accent); outline-offset:-1px; }
.alt-comp:hover { outline:1px dashed rgba(255,255,255,.4); outline-offset:-1px; }

/* Resize handles */
.alt-resize-handle { position:absolute; width:10px; height:10px; background:var(--accent); border:1px solid #fff; border-radius:2px; z-index:200; }
.alt-resize-se { bottom:-4px; right:-4px; cursor:se-resize; }
.alt-resize-sw { bottom:-4px; left:-4px; cursor:sw-resize; }
.alt-resize-ne { top:-4px; right:-4px; cursor:ne-resize; }
.alt-resize-nw { top:-4px; left:-4px; cursor:nw-resize; }

/* Editor panel */
.alt-ed-head { font-size:12px; font-weight:700; color:var(--text); margin-bottom:6px; display:flex; align-items:center; gap:6px; }
.alt-ed-close { cursor:pointer; margin-left:auto; color:var(--text3); font-size:14px; }
.alt-ed-close:hover { color:var(--text); }
.alt-ed-del { cursor:pointer; color:var(--red); font-size:10px; }
.alt-ed-del:hover { text-decoration:underline; }
.alt-ed-row { display:flex; align-items:center; gap:5px; margin-bottom:4px; font-size:11px; }
.alt-ed-row label { font-size:10px; color:var(--text2); flex-shrink:0; }
.alt-ed-row select, .alt-ed-row input[type="text"], .alt-ed-row input[type="number"] { flex:1; font-size:11px; padding:2px 4px; border:1px solid var(--border2); border-radius:3px; background:var(--bg2); color:var(--text); min-width:0; }
.alt-ed-row textarea { flex:1; font-size:11px; padding:3px 5px; border:1px solid var(--border2); border-radius:3px; background:var(--bg2); color:var(--text); resize:vertical; font-family:inherit; }
.alt-ed-row input[type="color"] { width:28px; height:22px; padding:1px; border:1px solid var(--border); border-radius:2px; cursor:pointer; }

/* Dual-thumb range (audio Loop Start/End) */
.aud-range { position:relative; flex:1; height:22px; }
.aud-range-track { position:absolute; top:9px; left:0; right:0; height:4px; background:var(--border2,#444); border-radius:2px; }
.aud-range-fill { position:absolute; top:9px; height:4px; background:var(--accent,#4a9eff); border-radius:2px; }
.aud-range input[type="range"] {
  position:absolute; top:0; left:0; width:100%; height:22px;
  margin:0; padding:0; background:transparent; pointer-events:none;
  -webkit-appearance:none; appearance:none;
}
.aud-range input[type="range"]::-webkit-slider-runnable-track { background:transparent; border:none; }
.aud-range input[type="range"]::-moz-range-track { background:transparent; border:none; }
.aud-range input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance:none; appearance:none;
  width:14px; height:14px; border-radius:50%;
  background:var(--accent,#4a9eff); border:2px solid #fff;
  cursor:pointer; pointer-events:auto; margin-top:-5px;
  box-shadow:0 1px 2px rgba(0,0,0,.4);
}
.aud-range input[type="range"]::-moz-range-thumb {
  width:14px; height:14px; border-radius:50%;
  background:var(--accent,#4a9eff); border:2px solid #fff;
  cursor:pointer; pointer-events:auto;
  box-shadow:0 1px 2px rgba(0,0,0,.4);
}

/* ── Playground mode (public AI Image Assistant) ───────────── */
/* Activated by body.playground (set by routes_playground when the URL
   token verifies). The playground operates on a real auto-managed slide
   in the channel, so all of canvas / drag / resize / multi-component /
   candidate placement run through the existing app code untouched. CSS
   only hides the surrounding chrome (header, sidebars, slide selector,
   editor panel) and pins the AI panel.

   The canvas background is fixed white — visitors can't change theme or
   slide bg color. */
body.playground #header,
body.playground #left-panel,
body.playground #thumb-bar,
body.playground #canvas-label,
body.playground #canvas-empty,
body.playground #comp-ed,
body.playground #ai-video-panel,
body.playground #lib-tray,
body.playground #tu-modal,
body.playground #footer {
  display: none !important;
}
/* AI panel rows that are advanced/internal-only and shouldn't appear in
   the public playground:
     • Make suggestions  — power-user prompt-rewriting toggle
     • Show style additions  — diagnostic surface for the prompt suffix */
body.playground #ai-elaborate-row,
body.playground #ai-additions-row {
  display: none !important;
}
body.playground #canvas-stage { background: #ffffff !important; }
body.playground #canvas-scroll { padding: 20px !important; }

/* Reserve the candidate-bar row even before any generation has fired,
   so the canvas position doesn't jump when the first batch lands.
   Watch mode keeps it hidden — the watcher doesn't need it. */
body.playground:not(.playground-watch) #candidate-bar {
  display: block !important;
}

/* Push the entire center column down so the fixed heading (~40px tall
   at top:8px) doesn't sit on top of the candidate bar / canvas. */
body.playground #center {
  padding-top: 50px;
}

/* Top-of-page heading. Russo One is loaded by the main template's
   <head>; "ai" inside "Sinaige" gets the brand red. */
#playground-heading {
  position: fixed;
  top: 8px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 200;
  font-family: 'Russo One', system-ui, sans-serif;
  font-size: 26px;
  letter-spacing: 0.6px;
  color: #222;
  white-space: nowrap;
  pointer-events: none;
  text-shadow: 0 1px 2px rgba(255,255,255,.6);
}
#playground-heading .ai-emph { color: #e53935; }
/* Always-on AI panel pinned to the top-right of the stage area. The
   playground hides #comp-ed (which the panel normally anchors to), so
   we override position via CSS instead of going through _positionAiPanel.
   No !important on top/right/left — that would block the drag handler's
   inline-style updates. The defaults below set the initial position;
   the drag (mousedown on #ai-panel-head, see panels.js) overrides them
   via element.style.top/left/right. */
body.playground #ai-panel {
  display: block !important;
  position: absolute !important;
  top: 20px;
  right: 20px;
  left: auto;
}

/* Click-to-start overlay shown when the background slide has audio or
   video components. Browsers won't play sound without a user gesture,
   so we collect one up front before kicking off media playback. */
#playground-start-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,.85);
  z-index: 9999;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  color: #fff;
  font-family: sans-serif;
  text-align: center;
}
#playground-start-overlay .play-icon {
  font-size: 48px; line-height: 1; margin-bottom: 16px;
}

/* Playground zoom slider — pinned bottom-left so it doesn't sit over
   the candidate bar at the top. Compact pill against the canvas. */
#playground-zoom {
  position: fixed;
  bottom: 20px;
  left: 20px;
  z-index: 200;
  display: flex;
  align-items: center;
  gap: 6px;
  background: rgba(0,0,0,.7);
  color: #fff;
  padding: 3px 8px;
  border-radius: 3px;
  box-shadow: 0 1px 4px rgba(0,0,0,.2);
  font-size: 11px;
}
#playground-zoom .zoom-label { font-weight: 600; }
#playground-zoom .zoom-value {
  min-width: 30px; text-align: right;
  font-variant-numeric: tabular-nums;
}
#playground-zoom input[type=range] { width: 90px; height: 14px; }

/* Playground action buttons — pinned to the viewport's right edge,
   stacked vertically with Duplicate above New Image. Bottom-anchored
   so they don't collide with the AI panel at the top-right. */
#playground-new-image,
#playground-duplicate {
  position: fixed;
  right: 20px;
  z-index: 200;
  background: var(--accent, #4a9eff);
  color: #fff;
  border: none;
  border-radius: 4px;
  padding: 8px 14px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  box-shadow: 0 2px 6px rgba(0,0,0,.25);
  width: 130px;
  text-align: center;
}
#playground-new-image:hover,
#playground-duplicate:hover { filter: brightness(1.1); }
#playground-new-image { bottom: 20px; }
#playground-duplicate { bottom: 60px; }

/* Inline <copy>…</> markup — click the wrapped span (or the appended
   monochrome copy icon) to copy the bounded text to the clipboard.
   Plain text styling so the wrap doesn't visually distort the
   slide content; the duplicated-rectangle icon is the affordance. */
.ed-copy {
  display: inline;
  cursor: pointer;
  user-select: text;
}
/* Just the LAST WORD + icon are non-breakable — the rest of the
   bounded text wraps normally so we don't end up clipping a long
   phrase by trying to keep the whole thing on one line. */
.ed-copy-tail {
  white-space: nowrap;
}

/* Bulleted lists from <ul>…<li>…</> markup. Tight padding so they fit
   comfortably inside narrow text components. */
.ed-ul {
  margin: 0.3em 0;
  padding-left: 1.4em;
  list-style: disc;
}
.ed-ul > li { margin: 0.1em 0; }
.ed-copy:focus-visible { outline: 2px solid var(--accent, #4a9eff); outline-offset: 2px; border-radius: 2px; }
.ed-copy-ico {
  display: inline-block;
  width: 1em;
  height: 1em;
  margin-left: 5px;
  vertical-align: -0.12em;
  color: #f5b700;
  /* Thin dark drop-shadow so the yellow stays visible against light
     backgrounds without losing the colour. */
  filter: drop-shadow(0 0 1px rgba(0,0,0,0.45));
  transition: color .15s ease, filter .15s ease;
}
.ed-copy:hover .ed-copy-ico {
  color: #ffcc1a;
  filter: drop-shadow(0 0 1.5px rgba(0,0,0,0.55));
}
/* "Copied!" confirmation pill — shows for ~1s then fades. */
.ed-copy-tip {
  position: fixed;
  z-index: 99999;
  background: rgba(20, 20, 20, 0.9);
  color: #fff;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 11px;
  font-family: system-ui, -apple-system, sans-serif;
  font-weight: 500;
  letter-spacing: 0.2px;
  pointer-events: none;
  transform: translate(-50%, calc(-100% - 2px));
  opacity: 0;
  transition: opacity .12s ease, transform .12s ease;
  white-space: nowrap;
  box-shadow: 0 2px 6px rgba(0,0,0,0.25);
}
.ed-copy-tip.show {
  opacity: 1;
  transform: translate(-50%, calc(-100% - 4px));
}

/* Background components — those authored on the ImageGen slide via the
   main app and committed (posted=TRUE). In the playground they render
   as a locked backdrop: no drag handles, no close button, no pointer
   events on the .cc itself so the canvas's drag handlers can't engage.
   Inline <copy> spans inside the text content opt in to pointer-
   events:auto so clicks on them still fire their clipboard handler. */
body.playground .cc.playground-bg .rh,
body.playground .cc.playground-bg .cc-x {
  display: none !important;
}
body.playground .cc.playground-bg {
  pointer-events: none;
}
body.playground .cc.playground-bg .ed-copy {
  pointer-events: auto;
}

/* Watch mode (read-only host view). Hide every interactive element and
   strip drag/resize/close affordances from all components. */
body.playground-watch #ai-panel,
body.playground-watch #ai-video-panel,
body.playground-watch #candidate-bar,
body.playground-watch #playground-new-image,
body.playground-watch #playground-duplicate {
  display: none !important;
}
body.playground-watch .cc .rh,
body.playground-watch .cc .cc-x {
  display: none !important;
}
body.playground-watch .cc { pointer-events: none; }

/* Inline text-markup cheat-sheet — shown by the `?` button next to the
   text-component content textarea. The button is a tiny circular badge;
   the popup is fixed-positioned next to it. */
.markup-help-btn {
  display: inline-block;
  margin-left: 6px;
  width: 16px; height: 16px;
  border-radius: 50%;
  background: var(--accent, #4a90e2);
  color: #fff;
  font-size: 11px;
  text-align: center;
  line-height: 16px;
  cursor: pointer;
  user-select: none;
  font-weight: bold;
  vertical-align: middle;
}
.markup-help-popup {
  position: fixed;
  z-index: 10000;
  background: #fff;
  color: #222;
  border: 1px solid #aaa;
  border-radius: 6px;
  box-shadow: 0 4px 14px rgba(0,0,0,.25);
  width: 360px;
  max-width: calc(100vw - 24px);
  font-size: 12px;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
.markup-help-popup .mhp-hd {
  padding: 6px 10px;
  border-bottom: 1px solid #e0e0e0;
  font-weight: bold;
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: #f6f6f6;
  border-radius: 6px 6px 0 0;
}
.markup-help-popup .mhp-x {
  cursor: pointer;
  font-weight: normal;
  font-size: 16px;
  color: #888;
  line-height: 1;
}
.markup-help-popup .mhp-x:hover { color: #000; }
.markup-help-popup .mhp-bd {
  padding: 8px 10px;
  max-height: 60vh;
  overflow: auto;
}
.markup-help-popup .mhp-bd p { margin: 4px 0; line-height: 1.5; }
.markup-help-popup code {
  background: #f0f0f0;
  padding: 1px 4px;
  border-radius: 3px;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 11px;
  white-space: nowrap;
}

/* Selection-based markup toolbar — sits between the "Text" label and the
   textarea inside the text-component editor. Buttons use mousedown
   preventDefault so clicking them doesn't blur the textarea, which would
   discard the selection visually. */
.markup-tb {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  margin: 4px 0 6px 0;
  align-items: center;
}
.markup-tb button {
  min-width: 22px;
  height: 22px;
  padding: 0 6px;
  font-size: 11px;
  cursor: pointer;
  background: var(--btn-bg, #e0e0e0);
  border: 1px solid var(--btn-border, #aaa);
  border-radius: 3px;
  line-height: 1;
  color: var(--btn-text, #222);
}
.markup-tb button:hover {
  background: var(--accent, #1a6ec0);
  color: #fff;
  border-color: var(--accent, #1a6ec0);
}
.markup-tb-sep {
  display: inline-block;
  width: 1px;
  height: 14px;
  background: var(--border2, #aaa);
  margin: 0 3px;
}

/* ── Player Management ─────────────────────────────────────── */
#player-mgmt { gap: 0; }
#pm-list-pane {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: 16px;
  min-width: 0;
}
#pm-toolbar { display:flex; gap:8px; margin-bottom:12px; align-items:center; }
#pm-search {
  flex: 1;
  max-width: 480px;
  padding: 6px 10px;
  border: 1px solid var(--border2, #aaa);
  border-radius: 4px;
  background: var(--bg2);
  color: var(--text);
  font-size: 13px;
}
/* Scroll container — list pane stays put, only the table scrolls.
   This also keeps the sticky thead working since a sticky element
   needs a scrollable ancestor. */
#pm-table-wrap {
  flex: 1;
  overflow: auto;
  border: 1px solid var(--border);
  border-radius: 4px;
}
#pm-table {
  border-collapse: collapse;
  font-size: 13px;
  width: 100%;
  /* Guarantee enough horizontal space for all 10 columns. If the
     pane is narrower than this, the wrapper scrolls horizontally —
     which is far better than crushing every column to nothing. */
  min-width: 1200px;
}
#pm-table th, #pm-table td {
  padding: 6px 10px;
  white-space: nowrap;
  vertical-align: middle;
  text-align: left;
}
#pm-table th {
  border-bottom: 2px solid var(--border);
  font-weight: 600;
  color: var(--text2);
  background: var(--bg2);
  position: sticky;
  top: 0;
  z-index: 1;
}
/* Sortable headers — pointer cursor + hover, with up/down arrow when
   active. The non-sortable Screen column is plain. */
#pm-table th[data-sort] {
  cursor: pointer;
  user-select: none;
}
#pm-table th[data-sort]:hover { background: var(--bg3); }
#pm-table th.pm-th-asc::after,
#pm-table th.pm-th-desc::after {
  display: inline-block;
  margin-left: 6px;
  font-size: 10px;
  color: var(--accent, #1a6ec0);
}
#pm-table th.pm-th-asc::after  { content: '\25B2'; }  /* ▲ */
#pm-table th.pm-th-desc::after { content: '\25BC'; }  /* ▼ */
#pm-table td {
  border-bottom: 1px solid var(--border);
}
/* Per-column minimums — each <th>:nth-child(n) also constrains the
   matching <td> column under auto-layout, so the table can't pinch
   any single column smaller than the header text needs. */
#pm-table th:nth-child(1)  { min-width: 70px; }   /* Status */
#pm-table th:nth-child(2)  { min-width: 100px; }  /* Up */
#pm-table th:nth-child(3)  { min-width: 90px; }   /* Screen */
#pm-table th:nth-child(4)  { min-width: 160px; }  /* Player Name */
#pm-table th:nth-child(5)  { min-width: 130px; }  /* Channel Name */
#pm-table th:nth-child(6)  { min-width: 80px; }   /* Channel */
#pm-table th:nth-child(7)  { min-width: 130px; }  /* IP Address */
#pm-table th:nth-child(8)  { min-width: 150px; }  /* Update Time */
#pm-table th:nth-child(9)  { min-width: 160px; }  /* Description */
#pm-table th:nth-child(10) { min-width: 110px; }  /* Group */
#pm-table tr.pm-trow { cursor: pointer; }
#pm-table tr.pm-trow:hover td { background: var(--bg3); }
#pm-table tr.pm-trow-selected td { background: rgba(255, 220, 40, 0.18); }

.pm-thumb {
  width: 64px;
  height: 36px;
  object-fit: cover;
  border-radius: 3px;
  background: var(--bg3);
  border: 1px solid var(--border);
  vertical-align: middle;
}
/* Placeholder thumbnail. Stripey background plus a centered tiny
   monitor glyph so the empty cell reads as "screen, not yet captured"
   instead of just looking broken. Inline SVG keeps it crisp at any
   pixel ratio with no extra HTTP request. */
.pm-thumb-placeholder {
  background-color: var(--bg3);
  background-image:
    repeating-linear-gradient(45deg,
      rgba(0,0,0,0.06), rgba(0,0,0,0.06) 3px,
      transparent 3px, transparent 6px),
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 16'><rect x='2' y='2' width='20' height='10' rx='1.2' fill='none' stroke='%23999' stroke-width='1.4'/><path d='M9 14h6M12 12v2' fill='none' stroke='%23999' stroke-width='1.2' stroke-linecap='round'/></svg>");
  background-position: center, center;
  background-repeat: repeat, no-repeat;
  background-size: auto, 60% 60%;
  display: inline-block;
}

.pm-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-right: 6px;
  vertical-align: middle;
}
.pm-dot.up   { background: #2e9b46; box-shadow: 0 0 0 2px rgba(46,155,70,0.18); }
.pm-dot.down { background: #c33;    box-shadow: 0 0 0 2px rgba(204,51,51,0.20); }

/* ── Detail pane ────────────────────────────────────────── */
#pm-detail-pane {
  width: 420px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  border-left: 1px solid var(--border);
  background: var(--panel-bg, var(--bg2));
  overflow: hidden;
}
#pm-detail-head {
  display: flex;
  align-items: center;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
  font-weight: 600;
  background: var(--bg2);
}
#pm-detail-head span { flex: 1; }
#pm-detail-head .pm-close {
  background: none;
  border: none;
  font-size: 20px;
  line-height: 1;
  color: var(--text3);
  cursor: pointer;
  padding: 0 4px;
}
#pm-detail-head .pm-close:hover { color: var(--text); }
#pm-detail-body {
  flex: 1;
  overflow-y: auto;
  padding: 12px 14px;
}

#pm-screen-wrap {
  position: relative;   /* anchor for the absolute-positioned expand btn */
  width: 100%;
  aspect-ratio: 16 / 9;
  background-color: var(--bg3);
  /* Same stripey placeholder pattern as the list thumbnail so the two
     read as variants of the same affordance. */
  background-image: repeating-linear-gradient(45deg,
    rgba(0,0,0,0.06), rgba(0,0,0,0.06) 4px,
    transparent 4px, transparent 8px);
  border: 1px solid var(--border);
  border-radius: 4px;
  margin-bottom: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
#pm-screen { max-width: 100%; max-height: 100%; }

/* Expand-to-fullsize button overlaid on the screenshot. Subtle by
   default, pops on hover. Hidden when there's no screenshot (the
   button's own display:none in the markup is set/unset by JS based on
   p.screen_thumbnail). */
#pm-screen-expand {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 24px;
  height: 24px;
  padding: 0;
  border: none;
  border-radius: 3px;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  cursor: pointer;
  opacity: 0.6;
  transition: opacity 0.12s, background 0.12s;
  display: flex;
  align-items: center;
  justify-content: center;
}
#pm-screen-wrap:hover #pm-screen-expand { opacity: 1; }
#pm-screen-expand:hover { background: rgba(0, 0, 0, 0.85); }

/* Fullscreen lightbox for the screenshot. Page-level, fixed-position;
   clicking the dark backdrop closes, the inner img stops propagation
   so the operator can hover/inspect without dismissing. */
#pm-lightbox {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.45);
  z-index: 10000;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
/* Frame shrinks to the image's natural size and provides the
   positioning context for the close button so the X anchors to the
   image's corner, not the viewport's. */
#pm-lightbox-frame {
  position: relative;
  display: inline-block;
  line-height: 0;   /* prevent inline-baseline gap below the img */
}
#pm-lightbox-img {
  display: block;
  max-width: 96vw;
  max-height: 96vh;
  cursor: default;
  box-shadow: 0 8px 40px rgba(0, 0, 0, 0.5);
  border-radius: 3px;
}

/* Round X button anchored to the image's top-right corner. Slightly
   overhangs so it reads as a "close on this thing" affordance. */
#pm-lightbox-close {
  position: absolute;
  top: -12px;
  right: -12px;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 2px solid #fff;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.75);
  color: #fff;
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.12s, transform 0.12s;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
}
#pm-lightbox-close:hover {
  background: rgba(0, 0, 0, 0.95);
  transform: scale(1.1);
}
#pm-screen-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  color: var(--text3);
  font-size: 12px;
}
#pm-screen-empty svg { color: var(--text3); opacity: 0.55; }

.pm-section { margin-bottom: 16px; }
.pm-section-title {
  font-size: 12px;
  font-weight: 600;
  color: var(--text2);
  margin-bottom: 6px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
.pm-row { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; font-size: 12px; }
.pm-row label { width: 110px; flex-shrink: 0; font-size: 11px; color: var(--text2); }
.pm-row input, .pm-row select {
  flex: 1;
  font-size: 12px;
  padding: 4px 6px;
  border: 1px solid var(--border2);
  border-radius: 3px;
  background: var(--bg2);
  color: var(--text);
}
.pm-update-row { justify-content: flex-end; gap: 10px; }
.pm-update-row #pm-update-msg { flex: 1; }

.pm-readonly { display: grid; grid-template-columns: 1fr 1fr; gap: 4px 12px; }
.pm-fact { display: flex; justify-content: space-between; font-size: 12px; padding: 2px 0; border-bottom: 1px dotted var(--border); }
.pm-fact > span:first-child { color: var(--text3); }
.pm-fact > span:last-child { color: var(--text); font-weight: 500; text-align: right; }

#pm-cmd-history {
  width: 100%;
  border-collapse: collapse;
  font-size: 11px;
}
#pm-cmd-history th {
  text-align: left;
  padding: 4px 6px;
  border-bottom: 1px solid var(--border);
  color: var(--text2);
  font-weight: 600;
}
#pm-cmd-history td {
  padding: 3px 6px;
  border-bottom: 1px solid var(--border);
}
.pm-cmd-status {
  display: inline-block;
  padding: 1px 6px;
  border-radius: 8px;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.4px;
}
.pm-cmd-queued        { background: #888;    color: #fff; }
.pm-cmd-sent          { background: #d89c1c; color: #fff; }
.pm-cmd-acked         { background: #2e9b46; color: #fff; }
.pm-cmd-failed        { background: #c33;    color: #fff; }
/* DebugOff entry stamped by the agent when its 30-min timer self-
   reverts — a different blue from the green operator-acked path. */
.pm-cmd-auto_reverted { background: #4a90b9; color: #fff; }

.pm-cmd-row { gap: 6px; }
#pm-cmd-select { flex: 0 1 140px; }
#pm-cmd-value  { flex: 0 1 100px; }
#pm-cmd-send   { flex-shrink: 0; }
