4882225751
Hand viewer: - stacks now decrement as players commit chips (street-aware "to"-amount accounting), showing e.g. 300 -> 285 after a 15 open, "all in" at 0; pot is computed from total committed (accurate, no double-counting raises) Theme (match the rec-theory-optimal look — warm black & orange, not Halloween): - deep near-black bg (#070707 / #0e0e0e panels), warm orange accent (#ff7a00), amber-gold secondary (#ffb347), muted green (#8fd694); warm dark borders - killed the neon-orange glows and the purple accents; chat app + all standalone pages (logs/self/journal/hand/recap/hands) on one palette Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
79 lines
3.8 KiB
HTML
79 lines
3.8 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
|
<meta name="theme-color" content="#070707" />
|
|
<title>Lyra — Recap</title>
|
|
<style>
|
|
:root{--bg:#070707;--bg-elev:#0e0e0e;--bg-line:#141414;--border:#2a1d12;--text:#e8e8e8;--fade:#8a8a8a;--accent:#ff7a00;}
|
|
*{box-sizing:border-box;}
|
|
html,body{margin:0;min-height:100%;background:var(--bg);color:var(--text);
|
|
font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;-webkit-text-size-adjust:100%;}
|
|
header{position:sticky;top:0;z-index:10;background:var(--bg-elev);border-bottom:1px solid var(--border);
|
|
padding:env(safe-area-inset-top) 14px 0;}
|
|
.topbar{display:flex;align-items:center;gap:10px;padding:12px 0;flex-wrap:wrap;}
|
|
.topbar h1{font-size:1.02rem;margin:0;font-weight:600;}
|
|
.topbar a.back{color:var(--accent);text-decoration:none;font-size:.92rem;}
|
|
.dl{margin-left:auto;background:#241400;border:1px solid var(--border);color:var(--accent);
|
|
border-radius:8px;padding:7px 12px;font-size:.85rem;text-decoration:none;}
|
|
main{max-width:740px;margin:0 auto;padding:18px 16px 48px;line-height:1.6;}
|
|
h1,h2,h3,h4{line-height:1.3;color:var(--text);}
|
|
main>h1:first-child{margin-top:0;}
|
|
h2{font-size:1.18rem;border-bottom:1px solid var(--border);padding-bottom:5px;margin-top:26px;color:var(--accent);}
|
|
h3{font-size:1.04rem;margin-top:18px;}
|
|
ul{padding-left:22px;} li{margin:3px 0;}
|
|
strong{color:var(--text);} hr{border:none;border-top:1px solid var(--border);margin:20px 0;}
|
|
code{background:rgba(255,255,255,.08);padding:1px 5px;border-radius:4px;font-size:.9em;}
|
|
.err{color:var(--fade);text-align:center;padding:46px 16px;}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<header>
|
|
<div class="topbar">
|
|
<h1>📋 Recap</h1>
|
|
<a class="back" href="/">← Chat</a>
|
|
<a class="back" href="/hands">Hands</a>
|
|
<a class="dl" id="dl">⬇ .md</a>
|
|
</div>
|
|
</header>
|
|
<main id="root"><p class="err">Loading recap…</p></main>
|
|
|
|
<script>
|
|
const bt = String.fromCharCode(96);
|
|
function esc(s){return String(s==null?'':s).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">");}
|
|
function inline(s){
|
|
const codeRe = new RegExp(bt+"([^"+bt+"]+)"+bt,"g");
|
|
return esc(s).replace(codeRe,"<code>$1</code>")
|
|
.replace(/\*\*([^*]+)\*\*/g,"<strong>$1</strong>")
|
|
.replace(/(^|[^*])\*([^*\n]+)\*/g,"$1<em>$2</em>");
|
|
}
|
|
function md(src){
|
|
const lines=String(src||"").replace(/\r\n/g,"\n").split("\n");
|
|
const out=[]; let list=null;
|
|
const flush=()=>{if(list){out.push("<ul>"+list.map(i=>"<li>"+inline(i)+"</li>").join("")+"</ul>");list=null;}};
|
|
for(const raw of lines){
|
|
const t=raw.replace(/\s+$/,""); let m;
|
|
if(!t.trim()){flush();continue;}
|
|
if(/^(-{3,}|\*{3,}|_{3,})$/.test(t.trim())){flush();out.push("<hr>");continue;}
|
|
if((m=t.match(/^(#{1,6})\s+(.*)$/))){flush();const n=m[1].length;out.push(`<h${n}>${inline(m[2])}</h${n}>`);continue;}
|
|
if((m=t.match(/^\s*[-*+]\s+(.*)$/))){(list=list||[]).push(m[1]);continue;}
|
|
flush();out.push("<p>"+inline(t)+"</p>");
|
|
}
|
|
flush(); return out.join("\n");
|
|
}
|
|
async function load(){
|
|
const id=location.pathname.split('/')[2];
|
|
document.getElementById('dl').href=`/recap/${id}/download`;
|
|
try{
|
|
const r=await fetch(`/recap/${id}/data`,{cache:'no-store'});
|
|
const d=await r.json();
|
|
if(!d.markdown){document.getElementById('root').innerHTML='<p class="err">No recap yet for this session. Ask Lyra to write one ("generate the recap").</p>';return;}
|
|
document.getElementById('root').innerHTML=md(d.markdown);
|
|
}catch(e){document.getElementById('root').innerHTML='<p class="err">Couldn\'t load the recap.</p>';}
|
|
}
|
|
load();
|
|
</script>
|
|
</body>
|
|
</html>
|