[object Object]

← back to Stock Vshape Viewer

yoloforever cycle 1: 3D encodings legend (height/volume/verdict/peak-glow/MA key), default-collapsed per Cody (avoids occluding 3D ticker labels)

b40722e05516a29f21e841a82a7f5e376f1710fc · 2026-08-28 00:50:10 -0700 · Steve

Files touched

Diff

commit b40722e05516a29f21e841a82a7f5e376f1710fc
Author: Steve <steve@designerwallcoverings.com>
Date:   Fri Aug 28 00:50:10 2026 -0700

    yoloforever cycle 1: 3D encodings legend (height/volume/verdict/peak-glow/MA key), default-collapsed per Cody (avoids occluding 3D ticker labels)
---
 public/app.js     |  4 ++++
 public/index.html | 18 ++++++++++++++++++
 2 files changed, 22 insertions(+)

diff --git a/public/app.js b/public/app.js
index e58635a..6711a90 100644
--- a/public/app.js
+++ b/public/app.js
@@ -580,6 +580,10 @@ const volnormBtn = document.getElementById('volnorm');
 const syncVolNorm = () => { volnormBtn.textContent = state.volNorm === 'global' ? '⬍ Vol: comparable' : '⬍ Vol: per-stock'; volnormBtn.classList.toggle('on', state.volNorm === 'global'); };
 syncVolNorm();
 volnormBtn.onclick = () => { state.volNorm = state.volNorm === 'global' ? 'per-stock' : 'global'; save(LS.volNorm, state.volNorm); syncVolNorm(); rebuildScene(); applyFilters(); };
+document.querySelector('#legend3d .lg-title').onclick = () => {
+  const hidden = document.getElementById('lg-body').classList.toggle('hidden');
+  document.getElementById('lg-toggle').textContent = hidden ? '▸' : '▾';
+};
 addEventListener('keydown', e => { if (e.key === 'Escape') { clearSelect(); document.getElementById('left').classList.remove('open'); } });
 addEventListener('resize', () => {
   camera.aspect = innerWidth / innerHeight; camera.updateProjectionMatrix(); renderer.setSize(innerWidth, innerHeight);
diff --git a/public/index.html b/public/index.html
index 7461fed..c22438f 100644
--- a/public/index.html
+++ b/public/index.html
@@ -107,6 +107,13 @@
   /* ===== bottom controls ===== */
   #ctl{position:fixed;bottom:14px;left:50%;transform:translateX(-50%);z-index:15;display:flex;gap:8px;padding:8px}
   #hint{position:fixed;bottom:60px;left:50%;transform:translateX(-50%);color:var(--dim);font-size:12px;z-index:5;pointer-events:none;opacity:.8}
+  #legend3d{position:fixed;bottom:14px;left:14px;z-index:12;padding:8px 10px;font-size:10.5px;color:var(--dim);opacity:.9}
+  #legend3d .lg-title{font-weight:700;color:var(--ink);font-size:11px;margin-bottom:4px;cursor:pointer;user-select:none}
+  #legend3d #lg-body{display:flex;flex-direction:column;gap:3px}
+  #legend3d #lg-body.hidden{display:none}
+  #legend3d .sw{display:inline-block;width:9px;height:9px;border-radius:2px;vertical-align:middle;margin-right:2px}
+  #legend3d .ln{display:inline-block;width:13px;height:2px;vertical-align:middle;margin-right:2px}
+  #legend3d .glowdot{display:inline-block;width:9px;height:9px;border-radius:50%;background:#fff;box-shadow:0 0 5px #9fd8ff;vertical-align:middle;margin-right:2px}
 
   /* ===== detail panel ===== */
   #detail{position:fixed;bottom:14px;right:14px;width:min(470px,46vw);max-height:calc(100vh - 80px);
@@ -254,6 +261,17 @@
 </div>
 <div id="hint">drag to orbit · scroll to zoom · click a layer for its chart · ☰ to screen</div>
 
+<div id="legend3d" class="glass">
+  <div class="lg-title">3D key <span id="lg-toggle">▸</span></div>
+  <div id="lg-body" class="hidden">
+    <div><b>height</b> = price · <b>thicker + brighter</b> = more volume</div>
+    <div><i class="sw" style="background:var(--pass)"></i>PASS &nbsp;<i class="sw" style="background:var(--fail)"></i>fails screen</div>
+    <div><span class="glowdot"></span> highest-volume day</div>
+    <div><i class="sw" style="background:var(--high)"></i>high &nbsp;<i class="sw" style="background:var(--trough)"></i>trough &nbsp;<i class="sw" style="background:var(--newhigh)"></i>recent high</div>
+    <div><i class="ln" style="background:var(--ma50)"></i>50-DMA &nbsp;<i class="ln" style="background:var(--ma200)"></i>200-DMA</div>
+  </div>
+</div>
+
 <div id="detail" class="glass">
   <div class="dh"><b id="d-tk"></b><span class="x" id="d-x">✕</span></div>
   <div class="sub" id="d-sub"></div>

← 5ff5470 3D volume reads: per-vertex volume color (bright=heavy/dim=l  ·  back to Stock Vshape Viewer  ·  yoloforever cycle 2: buy-score is CAP-DEPENDENT. Backtest no 7a16bf9 →