*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
:root{
  --ink:#1a1714;--ink-mid:#6b6460;--ink-light:#c8c2bc;
  --paper:#faf8f5;--warm:#f0ebe3;--accent:#c75b2e;--accent-dark:#9e421d;
  --accent-pale:#f5e8e1;--border:#ddd8d0;--success:#2e7d5b;
  --mono:'DM Mono',monospace;--serif:'Fraunces',serif;
}
body{font-family:var(--mono);background:var(--paper);color:var(--ink);min-height:100vh}
header{background:var(--ink);padding:1.75rem 3rem;display:flex;align-items:baseline;gap:1.25rem;flex-wrap:wrap}
header h1{font-family:var(--serif);font-size:1.9rem;font-weight:700;letter-spacing:-.03em;color:var(--paper)}
.tag{font-size:.68rem;background:var(--accent);color:#fff;padding:3px 9px;border-radius:2px;letter-spacing:.08em;text-transform:uppercase}
.subtitle{font-size:.75rem;color:#8a8480;margin-left:auto;letter-spacing:.04em}
main{width:100%;display:block;box-sizing:border-box}
.panel{background:#fff;border:1px solid var(--border);border-radius:4px;overflow:hidden}
.ph{background:var(--warm);border-bottom:1px solid var(--border);padding:.7rem 1.2rem;font-size:.67rem;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-mid);display:flex;align-items:center;gap:8px}
.pb{padding:1.35rem 1.2rem}
hr.dv{border:none;border-top:1px solid var(--border);margin:1.1rem 0}
.sec{font-size:.63rem;text-transform:uppercase;letter-spacing:.1em;color:var(--ink-mid);margin-bottom:.55rem}

/* dropzone */
#dz{border:2px dashed var(--border);border-radius:4px;padding:2rem 1rem;text-align:center;cursor:pointer;transition:.2s;background:var(--paper);position:relative}
#dz.over{border-color:var(--accent);background:var(--accent-pale)}
#dz input{position:absolute;inset:0;opacity:0;cursor:pointer;width:100%;height:100%}
.dz-icon{width:40px;height:40px;margin:0 auto .85rem;border:1.5px solid var(--border);border-radius:50%;display:flex;align-items:center;justify-content:center;color:var(--ink-mid)}
.dz-lbl{font-size:.75rem;color:var(--ink-mid);line-height:1.6}
.dz-lbl strong{color:var(--accent);font-weight:500}
#finfo{display:none;align-items:center;gap:8px;padding:.65rem .9rem;background:#edf6f0;border:1px solid #b8ddc7;border-radius:4px;margin-top:.9rem;font-size:.7rem;color:var(--success)}
#err{display:none;padding:.65rem .9rem;background:#fef0ef;border:1px solid #f5c4c2;border-radius:4px;font-size:.7rem;color:#a32d2d;margin-top:.9rem}

/* radio */
.rc{display:flex;flex-direction:column;gap:.4rem}
.ro{display:flex;align-items:flex-start;gap:.6rem;padding:.55rem .85rem;border:1px solid var(--border);border-radius:4px;cursor:pointer;transition:.15s;font-size:.72rem;line-height:1.5}
.ro:hover{border-color:var(--accent);background:var(--accent-pale)}
.ro input{accent-color:var(--accent);margin-top:2px;flex-shrink:0}
.ro .rt{font-weight:500;display:block}.ro .rd{color:var(--ink-mid);font-size:.66rem}

/* sub-panels */
#man-trim{display:none;margin-top:.85rem;padding:.85rem .9rem;background:var(--warm);border:1px solid var(--border);border-radius:4px}
#man-trim.on{display:block}
.hint{font-size:.62rem;color:var(--ink-mid);line-height:1.6;margin-top:.45rem}
.mgrid4{display:grid;grid-template-columns:1fr 1fr;gap:.45rem;margin-top:.55rem}
.mf{display:flex;flex-direction:column;gap:2px}
.mf label{font-size:.61rem;text-transform:uppercase;letter-spacing:.08em;color:var(--ink-mid)}
.mf input{padding:.38rem .55rem;border:1px solid var(--border);border-radius:3px;font-family:var(--mono);font-size:.72rem;background:#fff;color:var(--ink);width:100%}
.mf input:focus{outline:none;border-color:var(--accent)}

/* toggle */
/* action buttons */
.btn-row{display:flex;flex-direction:column;gap:.5rem;margin-top:1.35rem}
.btn{width:100%;padding:.75rem .5rem;border:none;border-radius:4px;font-family:var(--mono);font-size:.72rem;letter-spacing:.07em;text-transform:uppercase;cursor:pointer;transition:.15s;display:flex;align-items:center;justify-content:center;gap:7px}
.btn:disabled{opacity:.42;cursor:not-allowed}
.btn-outline{background:var(--warm);border:1px solid var(--border);color:var(--ink)}
.btn-outline:hover:not(:disabled){border-color:var(--accent);background:var(--accent-pale);color:var(--accent)}
.btn-primary{background:var(--accent);color:#fff}
.btn-primary:hover:not(:disabled){background:var(--accent-dark)}

#prog{display:none;margin-top:.9rem}
.pbg{background:var(--border);border-radius:2px;height:4px;overflow:hidden}
.pf{height:100%;background:var(--accent);border-radius:2px;width:0%;transition:width .3s}
#plbl{font-size:.63rem;color:var(--ink-mid);margin-top:.35rem;letter-spacing:.05em}

/* RIGHT panel */
.rpanel{min-height:640px}
#prev-c{padding:1.35rem;min-height:600px;display:flex;flex-direction:column;gap:1.25rem}
#ph{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;color:var(--ink-light);text-align:center}
#ph p{font-size:.7rem;margin-top:.9rem;letter-spacing:.06em}

/* tile controls bar */
.tile-bar{display:none;align-items:flex-end;gap:1.25rem;flex-wrap:wrap}
.tile-bar.on{display:flex}
.grid-dim{display:flex;align-items:center;gap:.45rem;font-size:.72rem}
.grid-dim input{width:64px !important;min-width:64px !important;height:34px !important;padding:.3rem .4rem !important;border:1px solid var(--border);border-radius:3px;font-family:var(--mono);font-size:.8rem;text-align:center;background:#fff;color:var(--ink);box-sizing:border-box}
.grid-dim input:focus{outline:none;border-color:var(--accent)}
.order-wrap{display:flex;flex-direction:column;gap:.3rem;flex:1;min-width:180px}
.order-row{display:flex;gap:.5rem}
.order-row input{flex:1;padding:.32rem .55rem;border:1px solid var(--border);border-radius:3px;font-family:var(--mono);font-size:.7rem;background:#fff;color:var(--ink)}
.order-row input:focus{outline:none;border-color:var(--accent)}
.order-row input.err-inp{border-color:#e24b4a}
.apply-btn{padding:.32rem .8rem;border:1px solid var(--border);border-radius:3px;font-family:var(--mono);font-size:.68rem;background:var(--warm);cursor:pointer;white-space:nowrap;color:var(--ink);transition:.15s}
.apply-btn:hover{border-color:var(--accent);background:var(--accent-pale);color:var(--accent)}

/* ── THE GRID ──
   Cells are exactly the size of the cropped page thumbnail.
   No gaps. Pages sit edge-to-edge so pattern lines visually align. */
#grid-scroll{overflow:auto;border:1px solid var(--border);border-radius:4px;background:var(--warm)}
#drag-grid{display:inline-grid;gap:0;line-height:0;font-size:0}
.cell{
  position:relative;cursor:grab;user-select:none;
  display:inline-block;line-height:0;font-size:0;
  outline:1px solid var(--border);
  transition:opacity .12s;
  background:#fff;
}
.cell:active{cursor:grabbing}
.cell.dragging{opacity:.3}
/* drag-over: accent outline inset so it doesn't shift layout */
.cell.drag-over{outline:2px solid var(--accent);z-index:2}
.cell canvas{display:block}
/* page number badge bottom-left */
.cell .pnum{
  position:absolute;bottom:4px;left:4px;
  background:rgba(26,23,20,.75);color:#faf8f5;
  font-size:10px;font-family:var(--mono);font-weight:500;
  padding:2px 6px;border-radius:2px;letter-spacing:.04em;
  pointer-events:none;line-height:1.4;
}
.cell .handle{position:absolute;top:3px;right:4px;color:rgba(255,255,255,.6);font-size:11px;pointer-events:none;line-height:1}
.cell.empty-slot{background:var(--warm);display:flex;flex-direction:column;align-items:center;justify-content:center;cursor:default;outline:1px dashed var(--border);gap:4px}
.empty-slot-trash{background:none;border:1px solid var(--border);border-radius:3px;color:var(--ink-light);cursor:pointer;padding:4px 6px;display:flex;align-items:center;justify-content:center;transition:.15s}
.empty-slot-trash:hover{background:#fee2e2;border-color:#f87171;color:#dc2626}
.cell.empty-slot span{font-size:.62rem;color:var(--ink-light);font-family:var(--mono)}

/* download */
#dl-bar{display:none;align-items:center;justify-content:space-between;padding:.9rem 1.2rem;background:#edf6f0;border:1px solid #b8ddc7;border-radius:4px;gap:1rem;flex-wrap:wrap}
.dl-info{font-size:.7rem;color:var(--success)}
.dl-info strong{font-weight:500;display:block;font-size:.76rem}
#dl-btn{padding:.55rem 1.1rem;background:var(--success);color:#fff;border:none;border-radius:4px;font-family:var(--mono);font-size:.7rem;letter-spacing:.08em;text-transform:uppercase;cursor:pointer;display:flex;align-items:center;gap:6px;flex-shrink:0}
#dl-btn:hover{opacity:.85}

/* ── FULL PATTERN PREVIEW MODAL ── */
#modal{display:none;position:fixed;inset:0;z-index:100;background:rgba(0,0,0,.93);flex-direction:column;align-items:center;padding:1rem 1.5rem 1.5rem;gap:0}
#modal.open{display:flex}
#modal-close{position:fixed;top:14px;right:18px;background:none;border:1px solid rgba(255,255,255,.3);border-radius:3px;color:rgba(255,255,255,.8);font-family:var(--mono);font-size:.7rem;padding:.35rem .85rem;cursor:pointer;letter-spacing:.06em;text-transform:uppercase;transition:.15s;z-index:101}
#modal-close:hover{border-color:#fff;color:#fff}
#modal-label{font-family:var(--mono);font-size:.63rem;color:rgba(255,255,255,.4);letter-spacing:.08em;padding:.5rem 0 0;flex-shrink:0}
#modal-toolbar{display:flex;align-items:center;gap:.6rem;padding:.5rem 0;flex-shrink:0}
#modal-toolbar button{background:none;border:1px solid rgba(255,255,255,.25);border-radius:3px;color:rgba(255,255,255,.8);font-family:var(--mono);font-size:.7rem;padding:.3rem .75rem;cursor:pointer;transition:.15s;letter-spacing:.05em}
#modal-toolbar button:hover{border-color:#fff;color:#fff}
#modal-zoom-val{font-family:var(--mono);font-size:.7rem;color:rgba(255,255,255,.5);min-width:3rem;text-align:center}
#modal-body{overflow:auto;line-height:0;flex:1;max-width:96vw;display:flex;align-items:flex-start;justify-content:flex-start}
#modal-body canvas{display:block;transform-origin:top left}

@media(max-width:780px){main{grid-template-columns:1fr}header{padding:1.5rem}.subtitle{margin-left:0}}
/* ── help modal ── */
#help-modal{display:none;position:fixed;inset:0;z-index:400;background:rgba(0,0,0,.7);align-items:center;justify-content:center;padding:1.5rem}
#help-modal.open{display:flex}
#help-box{background:#fff;border-radius:6px;max-width:600px;width:100%;max-height:85vh;overflow-y:auto;box-shadow:0 20px 60px rgba(0,0,0,.4)}
#help-box .hh{background:var(--ink);padding:1.25rem 1.5rem;border-radius:6px 6px 0 0;display:flex;align-items:center;justify-content:space-between}
#help-box .hh h2{font-family:var(--serif);font-size:1.2rem;font-weight:700;color:var(--paper);letter-spacing:-.02em}
#help-box .hh button{background:none;border:1px solid rgba(255,255,255,.25);border-radius:3px;color:rgba(255,255,255,.7);font-family:var(--mono);font-size:.68rem;padding:.3rem .7rem;cursor:pointer;transition:.15s}
#help-box .hh button:hover{border-color:#fff;color:#fff}
#help-body{padding:1.5rem}
#help-body h3{font-family:var(--mono);font-size:.7rem;text-transform:uppercase;letter-spacing:.1em;color:var(--accent);margin:1.1rem 0 .4rem;border-bottom:1px solid var(--border);padding-bottom:.3rem}
#help-body h3:first-child{margin-top:0}
#help-body p{font-size:.75rem;line-height:1.7;color:#333;margin-bottom:.5rem}
#help-body ul{padding-left:1.2rem;margin-bottom:.5rem}
#help-body li{font-size:.75rem;line-height:1.7;color:#333}
#help-body strong{color:var(--ink);font-weight:500}
#help-body .tip{background:var(--accent-pale);border-left:3px solid var(--accent);padding:.5rem .75rem;border-radius:0 3px 3px 0;font-size:.72rem;color:var(--accent-dark);margin:.75rem 0}
/* ── select mode ── */
#drag-grid.select-mode .sel-circle{display:flex !important}
/* ── select circle (top-right, shows on hover, always on in select mode) ── */
.cell .sel-circle{
  position:absolute;top:5px;right:5px;
  width:20px;height:20px;border-radius:50%;
  border:2px solid rgba(255,255,255,.85);
  background:rgba(0,0,0,.25);
  display:none;align-items:center;justify-content:center;
  cursor:pointer;z-index:5;transition:background .15s,border-color .15s;
  box-shadow:0 1px 3px rgba(0,0,0,.3);
}
.cell:hover .sel-circle{display:flex}
.cell.selected .sel-circle{
  background:var(--accent);border-color:var(--accent);display:flex;
}
.cell.selected .sel-circle::after{
  content:'\2713';color:#fff;font-size:11px;line-height:1;font-family:var(--mono);font-weight:500;
}
/* ── delete button on cell ── */
.cell .del-btn{
  position:absolute;top:4px;left:4px;
  width:20px;height:20px;border-radius:50%;
  background:rgba(199,91,46,.85);color:#fff;
  border:none;cursor:pointer;font-size:13px;line-height:1;
  display:none;align-items:center;justify-content:center;
  padding:0;transition:.15s;z-index:3;
  font-family:var(--mono);
}
.cell:hover .del-btn{display:flex}
.cell .del-btn:hover{background:var(--accent-dark);transform:scale(1.1)}
/* ── multiselect ── */
.cell.selected{outline:2.5px solid var(--accent);z-index:2}
.cell.selected::after{
  content:'\2713';position:absolute;top:4px;right:4px;
  width:18px;height:18px;border-radius:50%;
  background:var(--accent);color:#fff;
  font-size:10px;display:flex;align-items:center;justify-content:center;
  pointer-events:none;z-index:4;line-height:18px;text-align:center;
}
#sel-bar{display:none;align-items:center;justify-content:space-between;
  padding:.65rem 1.25rem;background:var(--ink);border-top:2px solid var(--accent);
  font-size:.72rem;color:var(--paper);gap:1rem;flex-wrap:wrap;
  position:fixed;bottom:0;left:0;right:0;z-index:300;
  box-shadow:0 -4px 20px rgba(0,0,0,.25)}
#sel-bar button{padding:.4rem 1rem;background:var(--accent);color:#fff;border:none;
  border-radius:3px;font-family:var(--mono);font-size:.68rem;letter-spacing:.06em;
  text-transform:uppercase;cursor:pointer;transition:.15s}
#sel-bar button:hover{background:var(--accent-dark)}
#sel-bar .sel-clear{background:none;border:1px solid rgba(255,255,255,.25);color:rgba(255,255,255,.7)}
#sel-bar .sel-clear:hover{border-color:#fff;color:#fff;background:none}
/* pad page bottom so content isn't hidden behind fixed bar */
body.has-selection{padding-bottom:56px}
/* ── multiselect ── */
let selectedSlots = new Set();
let lastSelectedSlot = null;
let selectMode = false;

function toggleSelect(slotIdx, shiftKey, ctrlKey) {
  const cols = Math.max(1, parseInt($('gcols').value) || 1);

  if (shiftKey && lastSelectedSlot !== null) {
    // Rectangular block selection &mdash; like Excel
    // Anchor corner: lastSelectedSlot, opposite corner: slotIdx
    const anchorRow = Math.floor(lastSelectedSlot / cols);
    const anchorCol = lastSelectedSlot % cols;
    const clickRow  = Math.floor(slotIdx / cols);
    const clickCol  = slotIdx % cols;

    const minRow = Math.min(anchorRow, clickRow);
    const maxRow = Math.max(anchorRow, clickRow);
    const minCol = Math.min(anchorCol, clickCol);
    const maxCol = Math.max(anchorCol, clickCol);

    // Clear previous shift-selection but keep anchor selected
    selectedSlots.clear();
    // Select all cells within the rectangle
    for (let r = minRow; r <= maxRow; r++) {
      for (let col = minCol; col <= maxCol; col++) {
        const idx = r * cols + col;
        if (idx < tileOrder.length && tileOrder[idx] > 0) {
          selectedSlots.add(idx);
        }
      }
    }
    // anchor stays fixed for further shift-clicks
  } else if (ctrlKey) {
    // Ctrl/Cmd: toggle individual tile, keep others
    if (selectedSlots.has(slotIdx)) {
      selectedSlots.delete(slotIdx);
    } else {
      selectedSlots.add(slotIdx);
      lastSelectedSlot = slotIdx;
    }
  } else {
    // Plain click: select just this tile, clear others
    if (selectedSlots.has(slotIdx) && selectedSlots.size === 1) {
      selectedSlots.clear();
      lastSelectedSlot = null;
    } else {
      selectedSlots.clear();
      selectedSlots.add(slotIdx);
      lastSelectedSlot = slotIdx;
    }
  }
  updateSelectionUI();
}

function clearSelection() {
  selectedSlots.clear();
  lastSelectedSlot = null;
  selectMode = false;
  updateSelectionUI();
  buildGrid();
}

function deleteSelected() {
  selectedSlots.forEach(idx => {
    if (tileOrder[idx] > 0) deletedPages.add(tileOrder[idx]);
    tileOrder[idx] = 0;
  });
  selectedSlots.clear();
  lastSelectedSlot = null;
  $('order-inp').value = tileOrder.join(',');
  updateSelectionUI();
  buildGrid();
}

function compactEmptyRows() {
  const cols = Math.max(1, parseInt($('gcols').value) || 1);
  const rows = Math.ceil(tileOrder.length / cols);
  const newOrder = [];
  for (let r = 0; r < rows; r++) {
    const row = [];
    for (let col = 0; col < cols; col++) {
      row.push(tileOrder[r * cols + col] || 0);
    }
    // Only drop rows that are ENTIRELY empty &mdash; never move pages between rows
    if (row.some(p => p > 0)) newOrder.push(...row);
  }
  tileOrder = newOrder;
  $('grows').value = Math.ceil(tileOrder.length / cols) || 1;
}

function deleteColumns() {
  if (selectedSlots.size === 0) return;
  const cols = Math.max(1, parseInt($('gcols').value) || 1);
  const rows = Math.max(1, parseInt($('grows').value) || 1);

  // Find which columns are involved in the selection
  const colsToDelete = new Set([...selectedSlots].map(idx => idx % cols));

  // Build new tileOrder with those columns removed
  const newCols = cols - colsToDelete.size;
  if (newCols < 1) return;

  const newOrder = [];
  for (let r = 0; r < rows; r++) {
    for (let col = 0; col < cols; col++) {
      if (!colsToDelete.has(col)) {
        newOrder.push(tileOrder[r * cols + col] || 0);
      }
    }
  }

  tileOrder = newOrder;
  $('gcols').value = newCols;
  selectedSlots.clear();
  lastSelectedSlot = null;
  $('order-inp').value = tileOrder.join(',');
  updateSelectionUI();
  buildGrid();
}

function enterSelectMode() {
  selectMode = true;
  const grid = $('drag-grid');
  if (grid) grid.classList.add('select-mode');
}

function exitSelectMode() {
  selectMode = false;
  const grid = $('drag-grid');
  if (grid) grid.classList.remove('select-mode');
}

function deleteRows() {
  if (selectedSlots.size === 0) return;
  const cols = Math.max(1, parseInt($('gcols').value) || 1);
  const rows = Math.max(1, parseInt($('grows').value) || 1);

  // Find which rows are involved in the selection
  const rowsToDelete = new Set([...selectedSlots].map(idx => Math.floor(idx / cols)));

  // Build new tileOrder with those rows removed
  const newRows = rows - rowsToDelete.size;
  if (newRows < 1) return;

  const newOrder = [];
  for (let r = 0; r < rows; r++) {
    if (!rowsToDelete.has(r)) {
      for (let col = 0; col < cols; col++) {
        newOrder.push(tileOrder[r * cols + col] || 0);
      }
    }
  }

  tileOrder = newOrder;
  $('grows').value = newRows;
  // Adjust extraRows count
  extraRows = Math.max(0, extraRows - rowsToDelete.size);
  updateRemBtn();
  selectedSlots.clear();
  lastSelectedSlot = null;
  selectMode = false;
  $('order-inp').value = tileOrder.join(',');
  updateSelectionUI();
  buildGrid();
}

function updateSelectionUI() {
  const count = selectedSlots.size;
  const bar = $('sel-bar');
  if (count > 0) {
    bar.style.display = 'flex';
    document.body.classList.add('has-selection');
    $('sel-count').textContent = count === 1 ? '1 page selected' : `${count} pages selected`;
    enterSelectMode();
  } else {
    bar.style.display = 'none';
    document.body.classList.remove('has-selection');
    exitSelectMode();
  }
  // Update cell selected state
  document.querySelectorAll('.cell').forEach(cell => {
    const idx = parseInt(cell.dataset.slot);
    cell.classList.toggle('selected', selectedSlots.has(idx));
  });
}

/* ── lightbox ── */
#lightbox{display:none;position:fixed;inset:0;z-index:200;background:rgba(0,0,0,.93);align-items:center;justify-content:center;flex-direction:column;padding:1rem 1.5rem 1.5rem;gap:0}
#lightbox.open{display:flex}
#lb-close{position:fixed;top:14px;right:18px;background:none;border:1px solid rgba(255,255,255,.3);border-radius:3px;color:rgba(255,255,255,.8);font-family:var(--mono);font-size:.7rem;padding:.35rem .85rem;cursor:pointer;letter-spacing:.06em;text-transform:uppercase;transition:.15s;z-index:201}
#lb-close:hover{border-color:#fff;color:#fff}
#lb-label{font-family:var(--mono);font-size:.63rem;color:rgba(255,255,255,.4);letter-spacing:.08em;padding:.5rem 0 0;flex-shrink:0}
#lb-toolbar{display:flex;align-items:center;gap:.6rem;padding:.5rem 0;flex-shrink:0}
#lb-toolbar button{background:none;border:1px solid rgba(255,255,255,.25);border-radius:3px;color:rgba(255,255,255,.8);font-family:var(--mono);font-size:.7rem;padding:.3rem .75rem;cursor:pointer;transition:.15s;letter-spacing:.05em}
#lb-toolbar button:hover{border-color:#fff;color:#fff}
#lb-zoom-val{font-family:var(--mono);font-size:.7rem;color:rgba(255,255,255,.5);min-width:3rem;text-align:center}
#lb-img-wrap{overflow:auto;line-height:0;flex:1;max-width:96vw;display:flex;align-items:flex-start;justify-content:flex-start}
#lb-img-wrap canvas{display:block;cursor:zoom-in;transform-origin:top left}
#lb-spinner{color:rgba(255,255,255,.5);font-family:var(--mono);font-size:.72rem;padding:3rem;letter-spacing:.06em}

/* hide number input spinners for trim boxes */
#mt::-webkit-inner-spin-button,#mt::-webkit-outer-spin-button,
#mb::-webkit-inner-spin-button,#mb::-webkit-outer-spin-button,
#ml::-webkit-inner-spin-button,#ml::-webkit-outer-spin-button,
#mr::-webkit-inner-spin-button,#mr::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}

/* ── grey cover box ── */

.cover-box {
  position:absolute;
  background:rgba(200,200,200,0.85);
  border:1px solid rgba(255,255,255,0.5);
  border-radius:2px;
  cursor:move;
  z-index:6;
  box-sizing:border-box;
  min-width:8px;min-height:8px;
  transition:box-shadow .15s;
}
.cover-box:hover {
  box-shadow:0 0 0 1.5px rgba(255,255,255,0.8), 0 0 0 3px rgba(80,80,80,0.35);
}
.cover-box .cb-handle {
  position:absolute;
  width:6px;height:6px;
  background:#fff;
  border:1px solid rgba(80,80,80,0.5);
  border-radius:50%;
  z-index:7;
  box-sizing:border-box;
  opacity:0;
  transition:opacity .15s;
}
.cover-box:hover .cb-handle { opacity:1; }
/* corners */
.cb-nw{top:-3px;left:-3px;cursor:nw-resize}
.cb-ne{top:-3px;right:-3px;cursor:ne-resize}
.cb-sw{bottom:-3px;left:-3px;cursor:sw-resize}
.cb-se{bottom:-3px;right:-3px;cursor:se-resize}
/* edges */
.cb-n{top:-3px;left:calc(50% - 3px);cursor:n-resize}
.cb-s{bottom:-3px;left:calc(50% - 3px);cursor:s-resize}
.cb-w{top:calc(50% - 3px);left:-3px;cursor:w-resize}
.cb-e{top:calc(50% - 3px);right:-3px;cursor:e-resize}


/* ── page labels ── */
.cell .pg-label {
  position:absolute;bottom:4px;left:4px;
  background:rgba(26,23,20,.72);color:#faf8f5;
  font-size:10px;font-family:var(--mono);font-weight:500;
  padding:2px 6px;border-radius:2px;letter-spacing:.04em;
  pointer-events:none;line-height:1.4;z-index:4;
}
.cell .label-input {
  position:absolute;bottom:4px;left:4px;
  width:52px;padding:2px 5px;
  background:rgba(255,255,255,.95);
  border:1.5px solid var(--accent);border-radius:2px;
  font-size:10px;font-family:var(--mono);font-weight:500;
  color:var(--ink);text-transform:uppercase;letter-spacing:.04em;
  z-index:10;outline:none;
}

/* App grid wrapper &mdash; keeps grid off main so WP doesn't constrain it */
.app-grid {
  display: grid;
  grid-template-columns: 330px 1fr;
  gap: 2rem;
  align-items: start;
  padding: 2rem 2rem 4rem;
  box-sizing: border-box;
  width: 100%;
}