← back to Wallco Ai
drunk-animals: 'Best of the night' rail on /live
768a775b837da9dcc95c9e18e924d83ece8718a5 · 2026-05-13 03:47:47 -0700 · SteveStudio2
/api/drunk-animals/best?n=3 returns top-N highest-saturation designs.
Live page pins a pink-tinted rail above the stream showing the 3 most
saturated covers with hover-lift, dark gradient overlay, and sat score.
Polls every 2 min.
Smoke-tested: top 3 = Rose Hiccup #2240 (orangutan, 0.75), Plum Carouse
#2156 (orangutan, 0.69), Rose Caprice #1537 (capybara, 0.68).
Files touched
Diff
commit 768a775b837da9dcc95c9e18e924d83ece8718a5
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date: Wed May 13 03:47:47 2026 -0700
drunk-animals: 'Best of the night' rail on /live
/api/drunk-animals/best?n=3 returns top-N highest-saturation designs.
Live page pins a pink-tinted rail above the stream showing the 3 most
saturated covers with hover-lift, dark gradient overlay, and sat score.
Polls every 2 min.
Smoke-tested: top 3 = Rose Hiccup #2240 (orangutan, 0.75), Plum Carouse
#2156 (orangutan, 0.69), Rose Caprice #1537 (capybara, 0.68).
---
server.js | 45 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/server.js b/server.js
index cdacd65..19ae4eb 100644
--- a/server.js
+++ b/server.js
@@ -2214,6 +2214,23 @@ app.get('/api/drunk-animals/feed', (req, res) => {
res.json({ count: rows.length, total: DESIGNS.filter(d => d.category === 'drunk-animals').length, designs: rows });
});
+// ── /api/drunk-animals/best — highest-saturation N drunk-animal designs.
+// Powers the "Best of the night" rail pinned to the top of /live.
+app.get('/api/drunk-animals/best', (req, res) => {
+ res.setHeader('Cache-Control', 'no-store');
+ const n = Math.min(12, Math.max(1, parseInt(req.query.n || '3', 10)));
+ const best = DESIGNS
+ .filter(d => d.category === 'drunk-animals')
+ .sort((a, b) => (b.saturation || 0) - (a.saturation || 0))
+ .slice(0, n)
+ .map(d => ({
+ id: d.id, title: d.title, image_url: d.image_url,
+ dominant_hex: d.dominant_hex, saturation: d.saturation,
+ motifs: d.motifs || [], url: `/design/${d.id}`,
+ }));
+ res.json({ best });
+});
+
// ── /api/drunk-animals/stats — derived snapshot for the live viewer's
// "tonight in numbers" bar. Animals are extracted from motifs[] (when
// llava tagged them) so the bar reflects what actually rendered, not
@@ -2280,6 +2297,14 @@ header a:hover { border-color:var(--pink); color:var(--pink) }
.stats-bar .animals { display:flex; gap:6px; flex-wrap:wrap; padding-left:14px }
.stats-bar .animal-pill { padding:3px 10px; border-radius:999px; background:rgba(255,121,198,.12); color:var(--pink); font-size:11px; white-space:nowrap }
.stats-bar .animal-pill strong { color:#fff; margin-left:4px; font-weight:600 }
+.best-rail { padding:24px 20px 8px; background:linear-gradient(180deg,rgba(255,121,198,.06),transparent) }
+.best-rail h2 { font-family:'Playfair Display',serif; font-weight:400; font-size:14px; margin:0 0 12px; letter-spacing:.2em; text-transform:uppercase; color:var(--pink) }
+.best-row { display:grid; grid-template-columns:repeat(auto-fit,minmax(280px,1fr)); gap:14px }
+.best-card { aspect-ratio:1/1; background-size:cover; background-position:center; border-radius:14px; position:relative; overflow:hidden; display:block; text-decoration:none; color:inherit; border:1px solid rgba(255,121,198,.25); transition:transform .25s ease, box-shadow .25s ease }
+.best-card:hover { transform:translateY(-3px); box-shadow:0 12px 28px rgba(255,121,198,.25) }
+.best-card .info { position:absolute; left:0; right:0; bottom:0; padding:10px 14px; background:linear-gradient(180deg,transparent,rgba(0,0,0,.7)); font-size:12px }
+.best-card .info .t { font-family:'Playfair Display',serif; font-size:16px; line-height:1.2; margin:0 }
+.best-card .info .id { font-size:10px; opacity:.7; letter-spacing:.08em; margin-top:2px }
main { padding:20px; max-width:1500px; margin:0 auto }
.grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(280px,1fr)); gap:18px }
.card { background:#1a0f1a; border:1px solid var(--line); border-radius:14px; overflow:hidden; position:relative; opacity:0; transform:translateY(-12px); animation:slidein .5s ease forwards }
@@ -2310,6 +2335,10 @@ main { padding:20px; max-width:1500px; margin:0 auto }
<div class="stat"><span class="stat-label">Avg saturation</span><span class="stat-value" id="s-sat">—</span></div>
<div class="animals" id="s-animals"></div>
</div>
+<section class="best-rail" id="best-rail" style="display:none">
+ <h2>Best of the night · most saturated 3</h2>
+ <div class="best-row" id="best-row"></div>
+</section>
<main>
<div class="grid" id="grid"></div>
<div class="empty" id="empty">Loading the menagerie…</div>
@@ -2367,6 +2396,20 @@ function updateNext() {
nextEl.textContent = 'next in ' + m + ':' + String(s).padStart(2,'0');
}
+async function pollBest() {
+ try {
+ const r = await fetch('/api/drunk-animals/best?n=3');
+ const j = await r.json();
+ if (!j.best || !j.best.length) return;
+ const rail = document.getElementById('best-rail');
+ const row = document.getElementById('best-row');
+ row.innerHTML = j.best.map(d => \`<a class="best-card" href="\${d.url}" target="_blank" rel="noopener" style="background-image:url('\${d.image_url}')">
+ <div class="info"><p class="t">\${d.title}</p><p class="id">#\${d.id} · sat \${(d.saturation||0).toFixed(2)}</p></div>
+ </a>\`).join('');
+ rail.style.display = 'block';
+ } catch (e) { console.warn('best poll failed', e); }
+}
+
async function pollStats() {
try {
const r = await fetch('/api/drunk-animals/stats');
@@ -2383,8 +2426,10 @@ async function pollStats() {
poll();
pollStats();
+pollBest();
setInterval(poll, 30_000);
setInterval(pollStats, 60_000);
+setInterval(pollBest, 120_000);
setInterval(updateNext, 1000);
</script>
</body></html>`);
← 4c0ff53 drunk-animals: /api/drunk-animals/stats + 'tonight in number
·
back to Wallco Ai
·
drunk-animals: generator status pill + auto-recap mode on /l 50ea14f →