===== DIFF /home/yeff/public_html/devon/panel/assets/css/panel.css <-> /home/yeff/public_html/devon/panel/_restore_layout/20260325_190044/panel.css.current =====
--- /home/yeff/public_html/devon/panel/_restore_layout/20260325_190044/panel.css.current	2026-03-23 13:31:11.312648930 -0300
+++ /home/yeff/public_html/devon/panel/assets/css/panel.css	2026-04-09 08:12:21.523371410 -0300
@@ -1,205 +1,162 @@
-:root{
-  --bg:#071427;
-  --bg2:#0b1d39;
-  --panel:#0d2142;
-  --panel2:#0f2850;
-  --line:rgba(133,161,210,.18);
-  --text:#eef4ff;
-  --muted:#9db0d2;
-  --blue:#5aa2ff;
-  --green:#18c58f;
-  --red:#ff646e;
-  --amber:#ffbf53;
-  --violet:#8a7dff;
-  --radius:22px;
-  --shadow:0 18px 42px rgba(0,0,0,.26);
-}
-
-*{box-sizing:border-box}
-html,body{margin:0;padding:0;background:linear-gradient(180deg,var(--bg),#08101f);color:var(--text);font:14px/1.45 Inter,system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif}
-button{font:inherit}
-pre{margin:0}
-
-.op-shell{
-  min-height:100vh;
-  display:grid;
-  grid-template-columns:300px minmax(0,1fr) 420px;
-  gap:20px;
-  padding:20px;
-}
-
-.op-sidebar,.card,.drawer-card{
-  background:linear-gradient(180deg,var(--panel),var(--bg2));
-  border:1px solid var(--line);
-  border-radius:var(--radius);
-  box-shadow:var(--shadow);
-}
-
-.op-sidebar{padding:18px;position:sticky;top:20px;height:calc(100vh - 40px);overflow:auto}
-.brand{display:flex;align-items:center;gap:12px;padding:6px 4px 16px}
-.brand-dot{width:14px;height:14px;border-radius:999px;background:#ffb000;box-shadow:0 0 0 4px rgba(255,176,0,.12)}
-.brand strong{display:block;font-size:32px;line-height:1}
-.brand span{display:block;color:var(--muted);margin-top:4px}
-
-.side-block + .side-block{margin-top:20px}
-.side-label{color:#9db0d2;text-transform:uppercase;font-size:12px;letter-spacing:.12em;margin-bottom:12px}
-.pill-row{display:flex;flex-wrap:wrap;gap:8px}
-.pill,.badge{
-  display:inline-flex;align-items:center;justify-content:center;
-  min-height:34px;padding:0 12px;border-radius:999px;
-  border:1px solid var(--line);background:rgba(255,255,255,.04);color:var(--text);font-weight:700
-}
-.pill.pass,.badge.pass{border-color:rgba(24,197,143,.35);color:#8ff2cf;background:rgba(24,197,143,.12)}
-.pill.fail,.badge.fail{border-color:rgba(255,100,110,.35);color:#ffb2b8;background:rgba(255,100,110,.12)}
-.pill.missing,.badge.missing{border-color:rgba(255,191,83,.35);color:#ffd99a;background:rgba(255,191,83,.12)}
-.pill.running,.badge.running{border-color:rgba(90,162,255,.35);color:#b9d6ff;background:rgba(90,162,255,.12)}
-.pill.pending,.badge.pending{border-color:rgba(138,125,255,.35);color:#cec8ff;background:rgba(138,125,255,.12)}
-.badge-blue{border-color:rgba(90,162,255,.35);color:#b9d6ff;background:rgba(90,162,255,.12)}
-.badge-violet{border-color:rgba(138,125,255,.35);color:#cec8ff;background:rgba(138,125,255,.12)}
-
-.stage-nav{display:flex;flex-direction:column;gap:10px}
-.stage-btn{
-  width:100%;text-align:left;border:1px solid var(--line);background:rgba(255,255,255,.02);
-  color:var(--text);border-radius:18px;padding:14px 14px;cursor:pointer;
-  display:flex;align-items:center;justify-content:space-between;gap:10px
-}
-.stage-btn:hover,.stage-btn.active{background:rgba(90,162,255,.12);border-color:rgba(90,162,255,.3)}
-.stage-btn small{display:block;color:var(--muted);font-size:12px}
-
-.op-main{min-width:0}
-.hero{
-  display:flex;align-items:flex-start;justify-content:space-between;gap:16px;
-  padding:14px 4px 20px
-}
-.eyebrow{font-size:12px;letter-spacing:.14em;color:#8eb5ff;text-transform:uppercase;margin-bottom:8px}
-.hero h1{margin:0 0 8px;font-size:42px;line-height:1.05}
-.hero p{margin:0;color:var(--muted);font-size:16px}
-.hero-actions{display:flex;flex-wrap:wrap;gap:10px}
-.btn{
-  border:1px solid var(--line);border-radius:16px;padding:12px 16px;cursor:pointer;
-  background:rgba(255,255,255,.04);color:var(--text);font-weight:700
-}
-.btn-primary{background:linear-gradient(180deg,#4f93ff,#3272df);border-color:transparent}
-.btn-secondary:hover{background:rgba(255,255,255,.08)}
-
-.layer-grid,
-.top-grid{
-  display:grid;
-  grid-template-columns:repeat(2,minmax(0,1fr));
-  gap:18px;
-  margin-bottom:18px;
-}
-.top-grid{grid-template-columns:repeat(3,minmax(0,1fr))}
-.runtime-grid{
-  display:grid;
-  grid-template-columns:repeat(3,minmax(0,1fr));
-  gap:18px;
-  margin-bottom:18px;
-}
-.workspace-grid{
-  display:grid;
-  grid-template-columns:minmax(0,1.08fr) minmax(0,1fr);
-  gap:18px;
-}
-.card{padding:18px;min-width:0}
-.card-top{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:14px}
-.card-title{font-size:12px;letter-spacing:.12em;color:#9db0d2;text-transform:uppercase}
-.stat-card h2{margin:0 0 8px;font-size:30px}
-.muted{color:var(--muted)}
-
-.layer-list,.step-list{list-style:none;padding:0;margin:0}
-.layer-list li,.step-list li{
-  display:flex;align-items:center;justify-content:space-between;gap:12px;
-  padding:10px 0;border-top:1px solid rgba(255,255,255,.06)
-}
-.layer-list li:first-child,.step-list li:first-child{border-top:0}
-
-.donut-wrap{display:flex;align-items:center;justify-content:center;min-height:168px}
-.donut{width:170px;height:170px;display:grid;place-items:center;position:relative}
-.donut svg{width:170px;height:170px;transform:rotate(-90deg)}
-.donut-center{
-  position:absolute;display:flex;flex-direction:column;align-items:center;justify-content:center;
-  text-align:center
-}
-.donut-center strong{font-size:30px;line-height:1}
-.donut-center span{font-size:12px;color:var(--muted);margin-top:6px}
-.step-state{font-size:11px;text-transform:uppercase;letter-spacing:.08em;color:#ffd99a}
-
-.mini-metric-grid{
-  display:grid;
-  grid-template-columns:repeat(2,minmax(0,1fr));
-  gap:12px;
-}
-.metric-box{
-  border:1px solid var(--line);
-  border-radius:16px;
-  padding:14px;
-  background:rgba(255,255,255,.025)
-}
-.metric-box .metric-label{
-  color:var(--muted);
-  text-transform:uppercase;
-  letter-spacing:.08em;
-  font-size:11px;
-  margin-bottom:8px
-}
-.metric-box .metric-value{
-  font-size:22px;
-  font-weight:800
-}
-.metric-box .metric-sub{
-  font-size:12px;
-  color:var(--muted);
-  margin-top:6px
-}
-
-.pipeline-board{display:flex;flex-direction:column;gap:10px;max-height:320px;overflow:auto;padding-right:4px}
-.pipeline-item{
-  border:1px solid var(--line);
-  border-radius:16px;
-  padding:14px;
-  background:rgba(255,255,255,.025)
-}
-.pipeline-item h4{margin:0 0 8px;font-size:16px}
-.pipeline-item p{margin:0 0 10px;color:var(--muted)}
-.pipeline-kv{display:flex;flex-wrap:wrap;gap:8px}
-
-.subcategory-grid{
-  display:grid;
-  grid-template-columns:repeat(2,minmax(0,1fr));
-  gap:14px;
-}
-.subcard{
-  border:1px solid var(--line);border-radius:18px;padding:14px;background:rgba(255,255,255,.025)
-}
-.subcard h3{margin:0 0 10px;font-size:18px;line-height:1.2}
-.sub-meta{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:10px}
-.sub-stats{display:flex;flex-wrap:wrap;gap:8px;margin-top:10px}
-
-.row-table{display:flex;flex-direction:column;gap:10px;max-height:calc(100vh - 340px);overflow:auto;padding-right:4px}
-.row-item{
-  border:1px solid var(--line);border-radius:16px;padding:14px;background:rgba(255,255,255,.025);cursor:pointer
-}
-.row-item h4{margin:0 0 8px;font-size:17px}
-.row-item p{margin:0 0 10px;color:var(--muted)}
-.row-kv{display:flex;flex-wrap:wrap;gap:8px}
-
-.op-drawer{position:sticky;top:20px;height:calc(100vh - 40px)}
-.drawer-card{height:100%;padding:18px;overflow:auto}
-.json-viewer{
-  background:#07111f;border:1px solid var(--line);border-radius:18px;padding:16px;
-  color:#bfd3f6;white-space:pre-wrap;word-break:break-word;min-height:calc(100% - 44px)
-}
-
-@media (max-width: 1480px){
-  .op-shell{grid-template-columns:280px minmax(0,1fr)}
-  .op-drawer{grid-column:1 / -1;position:relative;top:auto;height:auto}
-}
-@media (max-width: 1180px){
-  .layer-grid,.top-grid,.runtime-grid,.workspace-grid,.subcategory-grid{grid-template-columns:1fr}
-}
-@media (max-width: 1080px){
-  .op-shell{grid-template-columns:1fr}
-  .op-sidebar,.op-drawer{position:relative;top:auto;height:auto}
-  .hero{flex-direction:column}
-}
+/* Devon Operator Panel — panel.css v20260409 */
+:root {
+  --bg0:#0c1117;--bg1:#111820;--bg2:#141e2e;--bg3:#0e1520;
+  --border:rgba(255,255,255,0.07);--border2:rgba(255,255,255,0.04);
+  --text0:#dde3ef;--text1:#9aafc2;--text2:#5a6e82;--text3:#334455;
+  --blue:#2563eb;--blue-lt:#60a5fa;
+  --violet:#7c3aed;--violet-lt:#a78bfa;
+  --green:#22c55e;--amber:#f59e0b;--red:#f87171;
+  --mono:'IBM Plex Mono',monospace;--sans:'IBM Plex Sans',sans-serif;
+}
+*{box-sizing:border-box;margin:0;padding:0}
+html,body{height:100%;overflow:hidden;background:var(--bg0);font-family:var(--sans);color:var(--text0);font-size:13px}
+
+/* SHELL */
+#dp-shell{display:flex;height:100vh;overflow:hidden}
+
+/* LEFT */
+#dp-left{width:238px;flex-shrink:0;background:var(--bg1);border-right:1px solid var(--border);display:flex;flex-direction:column;overflow:hidden}
+#dp-brand{padding:14px 12px;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:10px;flex-shrink:0}
+#dp-logo{height:22px;width:auto;object-fit:contain}
+#dp-brand-name{font-size:13px;font-weight:600;color:#e8ecf5}
+#dp-brand-sub{font-size:8px;color:var(--text3);letter-spacing:1px;text-transform:uppercase;margin-top:2px}
+.tree-label{font-size:8px;color:var(--text3);letter-spacing:1.2px;text-transform:uppercase;padding:12px 12px 4px;font-weight:500;flex-shrink:0;font-family:var(--mono)}
+#dp-tree{flex:1;overflow-y:auto;padding-bottom:8px}
+#dp-tree::-webkit-scrollbar{width:3px}
+#dp-tree::-webkit-scrollbar-thumb{background:var(--border);border-radius:2px}
+
+/* PHASE */
+.ph-row{display:flex;align-items:center;gap:6px;padding:5px 10px 5px 8px;cursor:pointer;border-left:2px solid transparent;transition:background 0.1s;user-select:none}
+.ph-row:hover{background:rgba(255,255,255,0.03)}
+.ph-row.ph-active{background:rgba(37,99,235,0.07);border-left-color:var(--blue)}
+.ph-arrow{font-size:9px;color:var(--text3);width:12px;flex-shrink:0}
+.ph-arrow.open{color:var(--text2)}
+.ph-num{font-family:var(--mono);font-size:9px;color:var(--text3);width:18px;flex-shrink:0}
+.ph-row.ph-active .ph-num{color:var(--blue)}
+.ph-name{font-size:10px;color:var(--text2);flex:1;line-height:1.3}
+.ph-row.ph-active .ph-name{color:var(--blue-lt)}
+.ph-dot{width:5px;height:5px;border-radius:50%;flex-shrink:0}
+
+/* CATEGORY */
+.cat-row{display:flex;align-items:center;gap:6px;padding:3px 10px 3px 24px;cursor:pointer;border-left:2px solid transparent;transition:background 0.1s;margin-left:6px;user-select:none}
+.cat-row:hover{background:rgba(255,255,255,0.02)}
+.cat-row.cat-active{background:rgba(37,99,235,0.06);border-left-color:rgba(37,99,235,0.4)}
+.cat-arrow{font-size:8px;color:var(--text3);width:10px;flex-shrink:0}
+.cat-arrow.open{color:var(--text2)}
+.cat-name{font-size:10px;color:#445566;flex:1;line-height:1.3}
+.cat-row.cat-active .cat-name{color:#7ab4cc}
+.cat-dot{width:4px;height:4px;border-radius:50%;flex-shrink:0}
+
+/* BUCKET */
+.bk-row{display:flex;align-items:center;gap:6px;padding:2px 10px 2px 38px;cursor:pointer;margin-left:6px;border-left:2px solid transparent;user-select:none}
+.bk-row:hover{background:rgba(255,255,255,0.015)}

===== DIFF /home/yeff/public_html/devon/panel/assets/js/panel.js <-> /home/yeff/public_html/devon/panel/_restore_layout/20260325_190044/panel.js.current =====
--- /home/yeff/public_html/devon/panel/_restore_layout/20260325_190044/panel.js.current	2026-03-25 18:11:23.802640494 -0300
+++ /home/yeff/public_html/devon/panel/assets/js/panel.js	2026-04-09 08:12:45.118922299 -0300
@@ -1,250 +1,331 @@
-(function () {
-  const DATA_BASE = "data/";
+'use strict';
 
-  const els = {
-    globalPills: document.getElementById("global-pills"),
-    stageNav: document.getElementById("stage-nav"),
-    heroTitle: document.getElementById("hero-title"),
-    heroSubtitle: document.getElementById("hero-subtitle"),
-    stageOrderBadge: document.getElementById("stage-order-badge"),
-    selectedStageName: document.getElementById("selected-stage-name"),
-    selectedStageDesc: document.getElementById("selected-stage-desc"),
-    selectedStageTotal: document.getElementById("selected-stage-total"),
-    selectedStageDonut: document.getElementById("selected-stage-donut"),
-    selectedRuntimeBadge: document.getElementById("selected-runtime-badge"),
-    selectedPipelineSteps: document.getElementById("selected-pipeline-steps"),
-    hostStatusBadge: document.getElementById("host-status-badge"),
-    dockerStatusBadge: document.getElementById("docker-status-badge"),
-    hostRuntimeGrid: document.getElementById("host-runtime-grid"),
-    dockerRuntimeGrid: document.getElementById("docker-runtime-grid"),
-    pipelineRuntimeCount: document.getElementById("pipeline-runtime-count"),
-    pipelineRuntimeBoard: document.getElementById("pipeline-runtime-board"),
-    subcatCount: document.getElementById("subcat-count"),
-    subcategoryGrid: document.getElementById("subcategory-grid"),
-    rowCount: document.getElementById("row-count"),
-    rowTable: document.getElementById("row-table"),
-    drawerLabel: document.getElementById("drawer-label"),
-    jsonViewer: document.getElementById("json-viewer"),
-    btnOpenManifest: document.getElementById("btn-open-manifest"),
-    btnOpenContract: document.getElementById("btn-open-contract"),
-    btnOpenHost: document.getElementById("btn-open-host"),
-    btnOpenDocker: document.getElementById("btn-open-docker"),
-    btnOpenRuntime: document.getElementById("btn-open-runtime"),
-    dataViewerModal: document.getElementById("data-viewer-modal"),
-    btnCloseViewerModal: document.getElementById("btn-close-viewer-modal")
-  };
-
-  const state = {
-    manifest: null,
-    dataContract: null,
-    contentIndex: null,
-    matrix: null,
-    pipelines: null,
-    hostRuntime: null,
-    dockerRuntime: null,
-    runtimeStatus: null,
-    selectedStage: null
-  };
-
-  function openDataViewerModal() {
-    if (!els.dataViewerModal) return;
-    if (typeof els.dataViewerModal.showModal === "function") {
-      if (!els.dataViewerModal.open) els.dataViewerModal.showModal();
-      return;
-    }
-    els.dataViewerModal.setAttribute("open", "open");
-  }
-
-  function closeDataViewerModal() {
-    if (!els.dataViewerModal) return;
-    if (typeof els.dataViewerModal.close === "function" && els.dataViewerModal.open) {
-      els.dataViewerModal.close();
-      return;
-    }
-    els.dataViewerModal.removeAttribute("open");
-  }
-
-  function safeUpper(v) {
-    return String(v || "MISSING").toUpperCase();
-  }
-
-  function getBadgeClass(status) {
-    const s = safeUpper(status);
-    if (s === "PASS") return "pass";
-    if (s === "FAIL") return "fail";
-    if (s === "RUNNING") return "running";
-    if (s === "PENDING") return "pending";
-    return "missing";
-  }
-  const FILE_ALIASES = {
-    "host_runtime.json": ["panel_host_runtime.json"],
-    "docker_runtime.json": ["panel_docker_runtime.json"],
-    "runtime_status.json": ["panel_pipeline_runtime.json", "panel_runtime_status.json"]
-  };
-
-  function buildJsonCandidates(file) {
-    const aliases = FILE_ALIASES[file] || [];
-    const raw = [file].concat(aliases);
-    const out = [];
-    raw.forEach(function (name) {
-      out.push(DATA_BASE + name);
-      out.push(name);
-    });
-    return Array.from(new Set(out));
+const BUCKETS = [
+  'prerequisites',
+  'installation',
+  'configuration',
+  'validation',
+  'observable_evidence',
+  'failure_modes_recovery',
+  'completion_promotion'
+];
+
+const BUCKET_DESC = {
+  prerequisites:         'Required conditions, blockers and hard dependencies',
+  installation:          'File and artifact installation steps',
+  configuration:         'Configuration and binding steps',
+  validation:            'Validation gates and pass/fail criteria',
+  observable_evidence:   'Filesystem and runtime observable evidence',
+  failure_modes_recovery:'Known failure modes and recovery actions',
+  completion_promotion:  'Done criteria and promotion gate'
+};
+
+const G = {
+  phases: [], cats: [], data: {},
+  openPhases: new Set(), openCats: new Set(),
+  sel: { phaseId: null, catId: null, bucket: null }
+};
+
+async function init() {
+  try {
+    const [hub, host, docker, runtime, progress] = await Promise.all([
+      fetch('data/hub_index.json').then(r => r.json()),
+      fetch('data/host_runtime.json').then(r => r.json()).catch(() => null),
+      fetch('data/docker_runtime.json').then(r => r.json()).catch(() => null),
+      fetch('data/runtime_status.json').then(r => r.json()).catch(() => null),
+      fetch('data/project_progress.json').then(r => r.json()).catch(() => null)
+    ]);
+    G.phases = hub.phases || [];
+    G.cats = hub.categories || [];
+    G.data = { host, docker, runtime, progress };
+    renderTree();
+    renderDetail();
+    renderFooter();
+  } catch (e) {
+    document.getElementById('dp-tree').innerHTML =
+      '<div class="tree-err">Load error: ' + e.message + '</div>';
   }
+}
 
-  async function getJson(file) {
-    const candidates = buildJsonCandidates(file);
-    let lastErr = null;
-
-    for (const url of candidates) {
-      try {
-        const res = await fetch(url, { cache: "no-store" });
-        if (res.ok) return await res.json();
-
-        const text = await res.text();
-        const msg = String(text || "").slice(0, 300);
-
-        if (res.status === 404) {
-          lastErr = new Error("404 Not Found: " + url);
-          continue;
-        }
-
-        throw new Error("HTTP " + res.status + " @ " + url + " :: " + msg);
-      } catch (err) {
-        const msg = String(err && (err.message || err) || "");
-        if (/404|Not Found/i.test(msg)) {
-          lastErr = err;
-          continue;
+function phaseOfCat(cat) {
+  const m = (cat.badge || '').match(/\d+/);
+  if (!m) return 'phase-01';
+  return 'phase-' + String(parseInt(m[0])).padStart(2, '0');
+}
+
+function catsForPhase(phaseId) {
+  return G.cats.filter(c => phaseOfCat(c) === phaseId);
+}
+
+/* ── TREE ─────────────────────────────────────────── */
+
+function renderTree() {
+  let html = '';
+  for (const ph of G.phases) {
+    const isOpen = G.openPhases.has(ph.id);
+    const phActive = G.sel.phaseId === ph.id ? ' ph-active' : '';
+    const num = ph.step.replace('Phase ', '');
+    html += `<div class="ph-row${phActive}" data-ph="${ph.id}">
+      <span class="ph-arrow${isOpen ? ' open' : ''}">${isOpen ? '▾' : '▸'}</span>
+      <span class="ph-num">${num}</span>
+      <span class="ph-name">${ph.name}</span>
+      <span class="ph-dot d-plan"></span>
+    </div>`;
+    if (isOpen) {
+      for (const cat of catsForPhase(ph.id)) {
+        const isCatOpen = G.openCats.has(cat.id);
+        const catActive = G.sel.catId === cat.id ? ' cat-active' : '';
+        html += `<div class="cat-row${catActive}" data-ph="${ph.id}" data-cat="${cat.id}">
+          <span class="cat-arrow${isCatOpen ? ' open' : ''}">${isCatOpen ? '▾' : '▸'}</span>
+          <span class="cat-name">${cat.title}</span>
+          <span class="cat-dot d-plan"></span>
+        </div>`;
+        if (isCatOpen) {
+          BUCKETS.forEach((bk, i) => {
+            const bkActive = G.sel.catId === cat.id && G.sel.bucket === bk ? ' bk-active' : '';
+            html += `<div class="bk-row${bkActive}" data-ph="${ph.id}" data-cat="${cat.id}" data-bk="${bk}">
+              <span class="bk-name">${bk}</span>
+            </div>`;
+          });
         }
-        throw err;
       }
     }
-
-    throw lastErr || new Error("JSON MISSING: " + file + " :: " + candidates.join(" | "));
   }
+  document.getElementById('dp-tree').innerHTML = html;
+  bindTree();
+}
+
+function bindTree() {
+  document.querySelectorAll('.ph-row').forEach(el => {
+    el.addEventListener('click', () => {
+      const id = el.dataset.ph;
+      if (G.openPhases.has(id)) { G.openPhases.delete(id); G.openCats.clear(); G.sel.catId = null; G.sel.bucket = null; }
+      else { G.openPhases.add(id); }
+      G.sel.phaseId = id;
+      renderTree(); renderDetail();
+    });
+  });
+  document.querySelectorAll('.cat-row').forEach(el => {
+    el.addEventListener('click', e => {
+      e.stopPropagation();
+      const id = el.dataset.cat;
+      if (G.openCats.has(id)) { G.openCats.delete(id); G.sel.bucket = null; }
+      else { G.openCats.add(id); }
+      G.sel.phaseId = el.dataset.ph;
+      G.sel.catId = id;
+      G.sel.bucket = null;
+      renderTree(); renderDetail();
+    });
+  });
+  document.querySelectorAll('.bk-row').forEach(el => {
+    el.addEventListener('click', e => {
+      e.stopPropagation();
+      G.sel.phaseId = el.dataset.ph;
+      G.sel.catId = el.dataset.cat;
+      G.sel.bucket = el.dataset.bk;
+      renderTree(); renderDetail();
+    });
+  });
+}
 
-  async function getJsonOptional(name) {
-      try {
-        return await getJson(name);
-      } catch (err) {
-        const msg = String(err && (err.message || err) || "");
-        if (/404|Not Found/i.test(msg)) return null;
-        throw err;
-      }
-    }

===== DIFF /home/yeff/public_html/devon/panel/index.html <-> /home/yeff/public_html/devon/panel/_restore_layout/20260325_190044/index.html.current =====
--- /home/yeff/public_html/devon/panel/_restore_layout/20260325_190044/index.html.current	2026-03-25 18:54:38.859381102 -0300
+++ /home/yeff/public_html/devon/panel/index.html	2026-04-08 04:04:02.691729428 -0300
@@ -1,25 +1,29 @@
+<?php require_once __DIR__ . "/../auth_guard.php"; ?>
 <!DOCTYPE html>
 <html lang="en">
 <head>
   <meta charset="UTF-8" />
   <title>Devon Operator Panel</title>
   <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-  <link rel="stylesheet" href="assets/css/panel.css?v=layout_restore_1774475678" />
+  <link rel="icon" type="image/png" href="../assets/img/favicon-devon.png" />
+  <link rel="stylesheet" href="assets/css/panel.runtime.fix.20260408_1.css?v=1" />
 </head>
 <body>
   <div class="op-shell">
     <aside class="op-sidebar">
       <div class="brand">
-        <div class="brand-dot"></div>
-        <div>
-          <strong>Devon</strong>
-          <span>Operator Panel</span>
-        </div>
+        <img class="brand-logo" src="../assets/img/logodevon-white.png" alt="Devon" />
+        <span class="brand-subtitle">Operator Panel</span>
       </div>
 
       <section class="side-block">
+        <div class="side-label">Project Progress</div>
+        <div id="project-donut" class="sidebar-donut-wrap"></div>
+      </section>
+
+      <section class="side-block">
         <div class="side-label">Global Status</div>
-        <div id="global-pills" class="pill-row"></div>
+        <div id="global-pills" class="pill-row pill-row-compact"></div>
       </section>
 
       <section class="side-block">
@@ -98,6 +102,24 @@
           </div>
           <ul id="selected-pipeline-steps" class="step-list"></ul>
         </article>
+
+        <article class="card stat-card">
+          <div class="card-top">
+            <span class="card-title">Canonical Coverage</span>
+            <span id="canon-coverage-badge" class="badge badge-violet">—</span>
+          </div>
+          <div id="canon-coverage-donut" class="donut-wrap"></div>
+          <div id="canon-unmapped-list" class="canon-unmapped-list"></div>
+        </article>
+
+        <article id="authority-sources-card" class="card stat-card">
+          <div class="card-top">
+            <span class="card-title">Authority Sources</span>
+            <span id="authority-doc-count" class="badge badge-blue">—</span>
+          </div>
+          <div id="authority-doc-list" class="doc-link-list"></div>
+        </article>
+
       </section>
 
       <section class="runtime-grid">
@@ -142,23 +164,24 @@
           </div>
           <div id="row-table" class="row-table"></div>
         </article>
+
+
       </section>
     </main>
 
-    <dialog id="data-viewer-modal" class="drawer-card viewer-modal">
-      <section class="viewer-modal-shell">
+    <aside id="data-viewer-modal" class="op-drawer">
+      <section class="drawer-card">
         <div class="card-top">
-          <span class="card-title">Data Viewer</span>
-          <div class="viewer-modal-actions">
-            <span id="drawer-label" class="badge badge-violet">secondary</span>
-            <button id="btn-close-viewer-modal" type="button" class="badge badge-blue">Close</button>
-          </div>
+          <span class="card-title">Canon / Data Viewer</span>
+          <span id="drawer-label" class="badge badge-violet">secondary</span>
         </div>
         <pre id="json-viewer" class="json-viewer">Select a JSON source.</pre>
       </section>
-    </dialog>
+    </aside>
   </div>
 
-  <script src="assets/js/panel.js?v=layout_restore_1774475678"></script>
+  <script src="assets/js/panel.runtime.fix.20260408_1.js?v=1"></script>
+
+
 </body>
 </html>

