slipstream / static /picks.html
s-ttp's picture
Claude Opus 5.5
Picks panels: rank on recent activity; tighten the insider screen
50f32cd
Raw History Blame Contribute Delete
4.53 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Slipstream — Top 20</title>
<link rel="stylesheet" href="/static/app.css?v=20260820a">
<style>
/* dedicated top-20 category page — extends app.css */
.pk-wrap{max-width:900px;margin:0 auto;padding:26px 20px 70px}
.pk-back{color:var(--blue);text-decoration:none;font-size:13px}
.pk-head{margin:14px 0 4px;display:flex;align-items:baseline;gap:12px;flex-wrap:wrap}
.pk-head h2{margin:0;font-size:24px}
.pk-count{font-family:var(--mono);font-size:12px;color:var(--accent)}
.pk-asof{color:var(--faint);font-size:12px;margin:4px 0 18px;line-height:1.5}
.pk-item{background:var(--card);border:1px solid var(--line);border-radius:14px;
padding:16px 18px;margin-bottom:14px}
.pk-rank{font-family:var(--mono);font-size:12px;color:var(--faint);min-width:26px}
.pk-row{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
.pk-score{font-family:var(--mono);font-size:12px;color:var(--gold);margin-left:auto}
.pk-sec{margin-top:11px}
.pk-sec-t{font-size:12px;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);margin:0 0 6px}
.pk-sec ul{margin:0;padding-left:16px}
.pk-sec li{color:var(--ink);font-size:13px;line-height:1.55;margin:3px 0}
.pk-sec li a{color:var(--blue);text-decoration:none}
.pk-sec li a:hover{text-decoration:underline}
.pk-disc{color:var(--faint);font-size:12px;margin-top:22px;line-height:1.5}
.pk-loading{color:var(--muted);padding:30px 0}
</style>
</head>
<body>
<header>
<div class="brand">
<h1>Slipstream</h1>
<span class="brand-tag">smart-money · quality · trend-adaptive</span>
</div>
<a class="pk-back" href="/">‹ Back to fund</a>
</header>
<main class="pk-wrap">
<div class="pk-head"><h2 id="pk-title">Loading…</h2><span class="pk-count" id="pk-count"></span></div>
<p class="pk-asof" id="pk-asof"></p>
<div id="pk-list" class="pk-loading">Loading top 20…</div>
<p class="pk-disc" id="pk-disc"></p>
</main>
<script>
const TITLES = {
superinvestor: ["Super Investor Activity — Top 20", "Ranked by net guru activity: 2× new ≥$10M positions + adds − trims − 2× exits (13F, ~45-day lag)"],
insider: ["Insider Activity — Top 20", "Ranked by insider conviction over the last 30 days: SEC Form 4 open-market buys by officers/directors, LLM fraud-screened"],
news: ["News Momentum — Top 20", "Ranked by recency-weighted positive news sentiment × breadth (S&P 500, 30 days), LLM manipulation-screened"],
};
const esc = s => String(s ?? "").replace(/[&<>"']/g, c => ({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}[c]));
async function main() {
const panel = new URLSearchParams(location.search).get("panel") || "superinvestor";
const [title, hint] = TITLES[panel] || [panel, ""];
document.getElementById("pk-title").textContent = title;
document.title = `Slipstream — ${title}`;
const list = document.getElementById("pk-list");
try {
const r = await fetch(`/api/picks/${panel}?limit=20`);
if (!r.ok) throw new Error(`HTTP ${r.status}`);
const d = await r.json();
document.getElementById("pk-count").textContent = `${d.picks.length} names`;
document.getElementById("pk-asof").textContent = `${hint}. ${d.as_of || ""}`;
document.getElementById("pk-disc").textContent = d.disclaimer || "";
list.classList.remove("pk-loading");
list.innerHTML = d.picks.map((p, i) => {
const llm = p.llm ? `<span class="pick-llm ${esc((p.llm.verdict||"").toLowerCase())}">LLM: ${esc(p.llm.verdict)}${p.llm.reason ? " — " + esc(p.llm.reason) : ""}</span>` : "";
const secs = (p.details || []).map(sec => `
<div class="pk-sec">
<p class="pk-sec-t">${esc(sec.title)}</p>
<ul>${(sec.items || []).map(it =>
`<li>${it.href ? `<a href="${esc(it.href)}" target="_blank" rel="noopener">${esc(it.text)}</a>` : esc(it.text)}</li>`).join("")}
</ul>
</div>`).join("");
return `<div class="pk-item">
<div class="pk-row">
<span class="pk-rank">#${i + 1}</span>
<span class="pick-ticker">${esc(p.ticker)}</span>
<span class="pk-score">score ${esc(p.score)}</span>
</div>
<span class="pick-detail">${esc(p.detail)}</span>
${llm}${secs}
</div>`;
}).join("") || "<p class='muted'>No qualifying picks.</p>";
} catch (e) {
list.textContent = `Failed to load: ${e.message}`;
}
}
main();
</script>
</body>
</html>