diff --git a/lib/common/static/instance_theme.css b/lib/common/static/instance_theme.css
index 4eeb5be..623623b 100644
--- a/lib/common/static/instance_theme.css
+++ b/lib/common/static/instance_theme.css
@@ -3213,6 +3213,29 @@ html[data-theme="light"] .options-estimate-row {
font-size: 0.78rem;
color: #b8c0dc;
}
+.options-pos-live-layout {
+ display: flex;
+ flex-direction: column;
+ min-height: 0;
+ flex: 1;
+}
+.opt-pos-expanded-host {
+ flex-shrink: 0;
+ margin-top: 8px;
+ overflow: visible;
+}
+.opt-pos-expanded-host .opt-pos-card {
+ margin-bottom: 0;
+}
+.options-pos-live-pane--bars-only {
+ flex: 1;
+ min-height: 72px;
+ max-height: 140px;
+ overflow-y: auto;
+}
+.options-pos-subcard .options-pos-live-layout {
+ min-height: 0;
+}
.options-pos-live-pane {
flex: 1;
min-height: 100px;
@@ -3284,8 +3307,7 @@ html[data-theme="light"] .options-estimate-row {
background: #171d2a;
}
.opt-pos-accordion-item.is-expanded .opt-pos-bar {
- border-radius: 8px 8px 0 0;
- border-bottom-color: transparent;
+ border-color: #4a6fd8;
background: #171d2a;
}
.opt-pos-bar-main {
@@ -3337,19 +3359,6 @@ html[data-theme="light"] .options-estimate-row {
.opt-pos-accordion-item.is-expanded .opt-pos-bar-chevron {
transform: rotate(90deg);
}
-.opt-pos-accordion-body {
- border: 1px solid #2a3348;
- border-top: none;
- border-radius: 0 0 8px 8px;
- overflow: hidden;
- background: #141923;
-}
-.opt-pos-card--nested {
- margin-bottom: 0 !important;
- border: none !important;
- border-radius: 0 !important;
- background: transparent !important;
-}
.options-page-wrap .opt-pos-card .pos-card-symbol strong {
font-size: 0.78rem;
}
diff --git a/lib/common/static/options_panel.js b/lib/common/static/options_panel.js
index a8cf35b..524af2c 100644
--- a/lib/common/static/options_panel.js
+++ b/lib/common/static/options_panel.js
@@ -457,7 +457,7 @@
'
" +
- '
' +
- renderPositionCardInner(p) +
- "
"
+ ""
);
}
- function bindPositionActions(container) {
+ function renderExpandedPositionCard(p) {
+ return renderPositionCard(p);
+ }
+
+ function applyAccordionState(list) {
+ const wrap = document.getElementById("opt-pos-cards");
+ const expandedHost = document.getElementById("opt-pos-expanded-host");
+ const livePane = document.getElementById("opt-pos-live");
+ if (!wrap) return;
+ const expanded = (list || []).find(function (p) { return p.inst_id === state.expandedPosInst; }) || null;
+ wrap.querySelectorAll(".opt-pos-accordion-item").forEach(function (el) {
+ const open = el.getAttribute("data-inst") === state.expandedPosInst;
+ el.classList.toggle("is-expanded", open);
+ const btn = el.querySelector(".opt-pos-bar");
+ if (btn) btn.setAttribute("aria-expanded", open ? "true" : "false");
+ });
+ if (expandedHost) {
+ if (expanded) {
+ expandedHost.hidden = false;
+ expandedHost.setAttribute("aria-hidden", "false");
+ expandedHost.innerHTML = renderExpandedPositionCard(expanded);
+ expandedHost.querySelectorAll(".opt-close-btn").forEach(function (btn) {
+ btn.addEventListener("click", function (e) {
+ e.stopPropagation();
+ closePosition(btn.getAttribute("data-inst"), btn);
+ });
+ });
+ } else {
+ expandedHost.hidden = true;
+ expandedHost.setAttribute("aria-hidden", "true");
+ expandedHost.innerHTML = "";
+ }
+ }
+ if (livePane) {
+ livePane.classList.toggle("options-pos-live-pane--bars-only", !!(list && list.length >= 2));
+ }
+ }
+
+ function bindPositionActions(container, list) {
if (!container) return;
container.querySelectorAll(".opt-close-btn").forEach(function (btn) {
btn.addEventListener("click", function (e) {
@@ -516,15 +550,10 @@
if (!item) return;
const inst = item.getAttribute("data-inst");
state.expandedPosInst = state.expandedPosInst === inst ? null : inst;
- const wrap = document.getElementById("opt-pos-cards");
- wrap.querySelectorAll(".opt-pos-accordion-item").forEach(function (el) {
- const open = el.getAttribute("data-inst") === state.expandedPosInst;
- el.classList.toggle("is-expanded", open);
- const body = el.querySelector(".opt-pos-accordion-body");
- const btn = el.querySelector(".opt-pos-bar");
- if (body) body.hidden = !open;
- if (btn) btn.setAttribute("aria-expanded", open ? "true" : "false");
- });
+ applyAccordionState(list);
+ if (window.OptionsExpiryCountdown && OptionsExpiryCountdown.ensureTimer) {
+ OptionsExpiryCountdown.ensureTimer();
+ }
});
});
}
@@ -564,10 +593,19 @@
const d = await apiJson("/api/options/positions");
const wrap = document.getElementById("opt-pos-cards");
const empty = document.getElementById("opt-pos-empty");
+ const expandedHost = document.getElementById("opt-pos-expanded-host");
+ const livePane = document.getElementById("opt-pos-live");
const list = (d.ok && d.positions) || [];
wrap.innerHTML = "";
+ if (expandedHost) {
+ expandedHost.hidden = true;
+ expandedHost.setAttribute("aria-hidden", "true");
+ expandedHost.innerHTML = "";
+ }
if (!list.length) {
empty.style.display = "";
+ state.expandedPosInst = null;
+ if (livePane) livePane.classList.remove("options-pos-live-pane--bars-only");
return;
}
empty.style.display = "none";
@@ -575,23 +613,26 @@
wrap.classList.toggle("opt-pos-cards--accordion", multi);
if (multi) {
const ids = list.map(function (p) { return p.inst_id; });
- if (!state.expandedPosInst || ids.indexOf(state.expandedPosInst) < 0) {
- state.expandedPosInst = list[0].inst_id || null;
+ if (state.expandedPosInst && ids.indexOf(state.expandedPosInst) < 0) {
+ state.expandedPosInst = null;
}
list.forEach(function (p) {
const div = document.createElement("div");
- div.innerHTML = renderPositionAccordionItem(p, p.inst_id === state.expandedPosInst);
+ div.innerHTML = renderPositionBar(p, p.inst_id === state.expandedPosInst);
wrap.appendChild(div.firstChild);
});
+ applyAccordionState(list);
+ bindPositionActions(wrap, list);
} else {
state.expandedPosInst = null;
+ if (livePane) livePane.classList.remove("options-pos-live-pane--bars-only");
list.forEach(function (p) {
const div = document.createElement("div");
div.innerHTML = renderPositionCard(p);
wrap.appendChild(div.firstChild);
});
+ bindPositionActions(wrap, list);
}
- bindPositionActions(wrap);
if (window.OptionsExpiryCountdown && OptionsExpiryCountdown.ensureTimer) {
OptionsExpiryCountdown.ensureTimer();
}
@@ -617,11 +658,11 @@
if (closedEl) closedEl.textContent = String(d.total_closed || 0);
if (profitEl) {
profitEl.textContent = d.total_profit != null && d.total_profit > 0
- ? fmt(d.total_profit, 4) + " USDC" : (d.total_closed ? "0 USDC" : "—");
+ ? fmt(d.total_profit, 2) + " USDC" : (d.total_closed ? "0 USDC" : "—");
}
if (lossEl) {
lossEl.textContent = d.total_loss != null && d.total_loss > 0
- ? fmt(d.total_loss, 4) + " USDC" : (d.total_closed ? "0 USDC" : "—");
+ ? fmt(d.total_loss, 2) + " USDC" : (d.total_closed ? "0 USDC" : "—");
}
}
@@ -660,7 +701,7 @@
const tr = document.createElement("tr");
const prem = h.status === "closed" ? h.premium_received : h.premium_paid;
const pnl = h.realized_pnl;
- const pnlTxt = pnl != null ? fmt(pnl, 4) : "—";
+ const pnlTxt = pnl != null ? fmt(pnl, 2) : "—";
const pnlCls = pnl > 0 ? "pos-pnl-profit" : pnl < 0 ? "pos-pnl-loss" : "";
tr.innerHTML =
"