Claude Sonnet 4.6 (max)

AnthropicFebruary 2026

What it wrote

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Quantum Singularity</title>
<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700;900&family=Share+Tech+Mono&family=Rajdhani:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}

:root{
  --void:#030408;
  --deep:#060a12;
  --surface:#0c1120;
  --surface2:#101828;
  --surface3:#161f30;
  --border:rgba(96,165,250,.1);
  --border2:rgba(168,85,247,.18);
  --purple:#a855f7;
  --purple-dim:rgba(168,85,247,.5);
  --blue:#60a5fa;
  --cyan:#22d3ee;
  --gold:#fbbf24;
  --green:#34d399;
  --red:#f87171;
  --text:#dde4f0;
  --muted:#47586e;
  --font-d:'Orbitron',monospace;
  --font-m:'Share Tech Mono',monospace;
  --font-b:'Rajdhani',sans-serif;
}

html,body{width:100%;height:100%;overflow:hidden;background:var(--void);color:var(--text);font-family:var(--font-b);-webkit-font-smoothing:antialiased}

/* ── Starfield ── */
#sf{position:fixed;inset:0;z-index:0;pointer-events:none}

/* ── App shell ── */
#app{position:relative;z-index:1;display:flex;flex-direction:column;height:100vh;overflow:hidden}

/* ── Header ── */
header{
  flex-shrink:0;height:50px;
  display:flex;align-items:center;justify-content:space-between;
  padding:0 18px;
  background:linear-gradient(90deg,rgba(168,85,247,.07),rgba(6,10,18,.96),rgba(96,165,250,.07));
  border-bottom:1px solid var(--border2);
  backdrop-filter:blur(8px);
}
.h-title{display:flex;align-items:center;gap:9px}
.h-dot{width:7px;height:7px;border-radius:50%;background:var(--cyan);box-shadow:0 0 8px var(--cyan);animation:blink 2s ease-in-out infinite}
@keyframes blink{0%,100%{opacity:1}50%{opacity:.25}}
h1{
  font-family:var(--font-d);font-size:.95rem;font-weight:900;letter-spacing:3px;text-transform:uppercase;
  background:linear-gradient(90deg,var(--purple),var(--blue),var(--cyan));
  -webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;
}
.h-right{display:flex;align-items:center;gap:12px}
.save-lbl{font-family:var(--font-m);font-size:.6rem;color:var(--muted)}
#prestige-btn{
  font-family:var(--font-d);font-size:.55rem;font-weight:700;letter-spacing:1.5px;text-transform:uppercase;
  padding:7px 16px;
  background:linear-gradient(135deg,rgba(124,58,237,.2),rgba(79,70,229,.2));
  border:1px solid rgba(168,85,247,.35);color:var(--purple);border-radius:4px;cursor:pointer;
  transition:all .2s;position:relative;overflow:hidden;
}
#prestige-btn:not(:disabled):hover{border-color:var(--purple);color:#fff;box-shadow:0 0 22px rgba(168,85,247,.45),inset 0 0 20px rgba(168,85,247,.08);transform:translateY(-1px)}
#prestige-btn:disabled{opacity:.3;cursor:not-allowed}

/* ── Main 3-col ── */
#main{flex:1;display:grid;grid-template-columns:228px 1fr 268px;overflow:hidden;min-height:0}

/* ── Panels ── */
.panel{display:flex;flex-direction:column;overflow:hidden;border-right:1px solid var(--border);background:linear-gradient(180deg,rgba(12,17,32,.98),rgba(6,10,18,.98))}
.panel:last-child{border-right:none;border-left:1px solid var(--border)}
.p-scroll{flex:1;overflow-y:auto;overflow-x:hidden}
.p-scroll::-webkit-scrollbar{width:3px}
.p-scroll::-webkit-scrollbar-thumb{background:var(--border2);border-radius:2px}
.p-head{
  flex-shrink:0;padding:7px 13px;
  font-family:var(--font-d);font-size:.52rem;font-weight:700;letter-spacing:3px;text-transform:uppercase;color:var(--muted);
  border-bottom:1px solid var(--border);background:rgba(21,30,46,.7);
}

/* ── Resource tiers ── */
.r-tier{
  display:flex;align-items:center;justify-content:space-between;
  padding:6px 13px;border-bottom:1px solid rgba(96,165,250,.05);
  opacity:0;transform:translateX(-12px);transition:opacity .45s,transform .45s,background .15s;
}
.r-tier.vis{opacity:1;transform:translateX(0)}
.r-tier:hover{background:rgba(96,165,250,.04)}
.r-left{display:flex;align-items:center;gap:8px}
.r-ico{font-size:1.05rem;width:22px;text-align:center}
.r-name{font-size:.68rem;font-weight:600;letter-spacing:.5px;color:var(--muted);text-transform:uppercase}
.r-right{text-align:right}
.r-val{font-family:var(--font-m);font-size:.82rem;color:var(--text)}
.r-rate{font-family:var(--font-m);font-size:.62rem;color:var(--cyan)}

/* ── Essence block ── */
.ess-block{
  margin:8px 11px;padding:9px 12px;
  background:linear-gradient(135deg,rgba(251,191,36,.07),rgba(168,85,247,.07));
  border:1px solid rgba(251,191,36,.2);border-radius:6px;
}
.ess-lbl{font-family:var(--font-d);font-size:.5rem;letter-spacing:2px;color:var(--gold);text-transform:uppercase;margin-bottom:2px}
.ess-val{font-family:var(--font-m);font-size:1.05rem;color:var(--gold);text-shadow:0 0 12px rgba(251,191,36,.45)}
.ess-bonus{font-size:.62rem;color:var(--muted);margin-top:1px}

/* ── Stats ── */
.stats-blk{padding:9px 13px;border-bottom:1px solid var(--border)}
.stat-row{display:flex;justify-content:space-between;align-items:baseline;padding:2px 0}
.stat-lbl{font-size:.66rem;color:var(--muted);font-weight:500}
.stat-v{font-family:var(--font-m);font-size:.7rem;color:var(--blue)}

/* ── Center panel ── */
#ctr{
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:22px;
  position:relative;overflow:hidden;
  background:radial-gradient(ellipse at 50% 38%,rgba(168,85,247,.06),transparent 65%);
}
#ctr::before{
  content:'';position:absolute;width:420px;height:420px;border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,rgba(168,85,247,.04),transparent 70%);
  animation:amb 9s ease-in-out infinite alternate;
}
@keyframes amb{0%{transform:scale(.85) translate(-20px,15px)}100%{transform:scale(1.15) translate(20px,-15px)}}

/* ── Singularity button ── */
.s-wrap{position:relative;display:flex;align-items:center;justify-content:center;width:240px;height:240px}
.halo1{
  position:absolute;inset:-7px;border-radius:50%;
  background:conic-gradient(from 0deg,transparent 0deg,rgba(168,85,247,.85) 45deg,transparent 85deg,rgba(96,165,250,.85) 145deg,transparent 185deg,rgba(34,211,238,.85) 245deg,transparent 285deg,rgba(168,85,247,.5) 345deg,transparent);
  animation:spin 2.8s linear infinite;
  -webkit-mask:radial-gradient(farthest-side,transparent calc(100% - 2.5px),#fff calc(100% - 1.5px));
  mask:radial-gradient(farthest-side,transparent calc(100% - 2.5px),#fff calc(100% - 1.5px));
}
.halo2{
  position:absolute;inset:-15px;border-radius:50%;
  background:conic-gradient(from 180deg,transparent,rgba(34,211,238,.45) 70deg,transparent 130deg,rgba(251,191,36,.3) 200deg,transparent 260deg,rgba(96,165,250,.4) 330deg,transparent);
  animation:spin 4.5s linear infinite reverse;
  -webkit-mask:radial-gradient(farthest-side,transparent calc(100% - 1.5px),#fff calc(100% - .5px));
  mask:radial-gradient(farthest-side,transparent calc(100% - 1.5px),#fff calc(100% - .5px));
}
@keyframes spin{from{transform:rotate(0)}to{transform:rotate(360deg)}}

#sbtn{
  width:180px;height:180px;border-radius:50%;
  border:2px solid rgba(168,85,247,.28);cursor:pointer;
  position:relative;overflow:hidden;
  background:radial-gradient(circle at 37% 34%,rgba(185,105,255,.75),transparent 44%),
             radial-gradient(circle at 64% 66%,rgba(55,25,140,.65),transparent 44%),
             radial-gradient(circle at 50% 50%,#100422 30%,#070b1c 100%);
  box-shadow:0 0 28px rgba(168,85,247,.55),0 0 60px rgba(168,85,247,.22),0 0 100px rgba(168,85,247,.1),
             inset 0 0 30px rgba(0,0,0,.65),inset 0 0 60px rgba(168,85,247,.08);
  transition:transform .12s cubic-bezier(.34,1.56,.64,1),box-shadow .2s;
  user-select:none;-webkit-user-select:none;
}
#sbtn::before{
  content:'';position:absolute;inset:0;border-radius:50%;
  background:conic-gradient(from 0deg at 50% 50%,transparent,rgba(168,85,247,.1) 90deg,transparent 180deg,rgba(96,165,250,.07) 270deg,transparent);
  animation:spin 7s linear infinite;
}
#sbtn::after{
  content:'';position:absolute;inset:0;border-radius:50%;
  background:radial-gradient(circle at 50% 0%,rgba(255,255,255,.06),transparent 50%);
}
#sbtn:hover{
  box-shadow:0 0 40px rgba(168,85,247,.75),0 0 80px rgba(168,85,247,.38),0 0 120px rgba(168,85,247,.18),
             inset 0 0 40px rgba(168,85,247,.14);
}
#sbtn:active{transform:scale(.94)}
.btn-c{
  position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;justify-content:center;
  height:100%;gap:3px;pointer-events:none;
}
.btn-em{
  font-size:2.7rem;
  filter:drop-shadow(0 0 14px rgba(168,85,247,.9)) drop-shadow(0 0 28px rgba(168,85,247,.4));
  animation:flt 3.2s ease-in-out infinite;
}
@keyframes flt{0%,100%{transform:translateY(0) scale(1)}50%{transform:translateY(-5px) scale(1.05)}}
.btn-lbl{font-family:var(--font-d);font-size:.48rem;font-weight:900;letter-spacing:4px;text-transform:uppercase;color:rgba(255,255,255,.92);text-shadow:0 0 10px rgba(168,85,247,.8)}
.btn-pw{font-family:var(--font-m);font-size:.65rem;color:var(--cyan);text-shadow:0 0 8px rgba(34,211,238,.5)}

/* Click fx layer */
.fx{position:absolute;inset:0;pointer-events:none;overflow:visible}

/* ── Production info ── */
.prod-info{text-align:center}
.prod-qps{font-family:var(--font-m);font-size:1.45rem;color:var(--cyan);text-shadow:0 0 14px rgba(34,211,238,.45);line-height:1}
.prod-lbl{font-size:.6rem;color:var(--muted);letter-spacing:2px;text-transform:uppercase;margin-top:2px;font-weight:600}

/* ── Milestone ── */
.ms-wrap{width:256px}
.ms-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:5px}
.ms-name{font-family:var(--font-d);font-size:.52rem;color:var(--muted);letter-spacing:1.5px;text-transform:uppercase}
.ms-pct{font-family:var(--font-m);font-size:.65rem;color:var(--purple)}
.ms-track{height:3px;background:rgba(255,255,255,.06);border-radius:2px;overflow:hidden}
.ms-fill{height:100%;background:linear-gradient(90deg,var(--purple),var(--cyan));border-radius:2px;transition:width .5s ease;box-shadow:0 0 8px rgba(168,85,247,.55)}

/* ── Buy toggle ── */
.buy-tog{display:flex;gap:4px;padding:7px 10px;background:rgba(21,30,46,.45);border-bottom:1px solid var(--border);flex-shrink:0}
.buy-btn{
  flex:1;padding:4px 0;font-family:var(--font-d);font-size:.48rem;font-weight:700;letter-spacing:1px;
  color:var(--muted);background:transparent;border:1px solid var(--border);border-radius:3px;
  cursor:pointer;transition:all .15s;text-transform:uppercase;
}
.buy-btn:hover{color:var(--text);border-color:rgba(96,165,250,.3)}
.buy-btn.act{background:rgba(168,85,247,.15);border-color:var(--purple);color:var(--purple)}

/* ── Generator card ── */
.gen{
  padding:10px 13px;border-bottom:1px solid rgba(96,165,250,.05);
  cursor:pointer;transition:background .15s;position:relative;
}
.gen:hover:not(.gen-lock){background:rgba(168,85,247,.055)}
.gen.gen-lock{opacity:.28;cursor:not-allowed}
.gen.gen-aff{background:rgba(168,85,247,.04)}
.gen.gen-aff::before{content:'';position:absolute;left:0;top:0;bottom:0;width:2px;background:var(--purple);box-shadow:0 0 8px rgba(168,85,247,.6)}
.gen-top{display:flex;justify-content:space-between;align-items:center;margin-bottom:3px}
.gen-lft{display:flex;align-items:center;gap:6px}
.gen-ico{font-size:.95rem}
.gen-nm{font-size:.77rem;font-weight:600;letter-spacing:.3px}
.gen-cnt{font-family:var(--font-m);font-size:.88rem;font-weight:700;color:var(--purple);min-width:26px;text-align:right}
.gen-dsc{font-size:.6rem;color:var(--muted);margin-bottom:4px}
.gen-bot{display:flex;justify-content:space-between;align-items:center}
.gen-cost{font-family:var(--font-m);font-size:.68rem;color:var(--gold)}
.gen-cost.aff{color:var(--green)}
.gen-prod{font-family:var(--font-m);font-size:.6rem;color:var(--cyan)}

/* ── Bottom ── */
#bot{flex-shrink:0;height:220px;border-top:1px solid var(--border2);display:flex;flex-direction:column;background:linear-gradient(180deg,rgba(12,17,32,.98),rgba(6,10,18,.99))}
.tab-bar{display:flex;border-bottom:1px solid var(--border);flex-shrink:0;background:rgba(21,30,46,.55)}
.tab-btn{
  padding:8px 18px;font-family:var(--font-d);font-size:.5rem;font-weight:700;letter-spacing:2px;text-transform:uppercase;
  color:var(--muted);background:none;border:none;border-bottom:2px solid transparent;cursor:pointer;transition:all .2s;
}
.tab-btn:hover:not(.act){color:var(--text)}
.tab-btn.act{color:var(--purple);border-bottom-color:var(--purple)}
.tab-pane{display:none;flex:1;overflow-y:auto;overflow-x:hidden;padding:10px 13px;gap:8px;flex-wrap:wrap;align-content:flex-start}
.tab-pane::-webkit-scrollbar{width:3px}
.tab-pane::-webkit-scrollbar-thumb{background:var(--border2);border-radius:2px}
.tab-pane.act{display:flex}
.tab-empty{color:var(--muted);font-size:.75rem;padding:8px;font-style:italic}

/* ── Upgrade card ── */
.up-card{
  width:148px;flex-shrink:0;background:var(--surface2);border:1px solid var(--border);
  border-radius:6px;padding:9px;cursor:pointer;transition:all .18s;
}
.up-card:hover:not(.up-b):not(.up-l){border-color:var(--purple);box-shadow:0 0 14px rgba(168,85,247,.35);transform:translateY(-2px)}
.up-card.up-b{opacity:.5;cursor:default;border-color:rgba(52,211,153,.2);background:rgba(52,211,153,.03)}
.up-card.up-l{opacity:.22;cursor:not-allowed;filter:grayscale(.8)}
.up-card.up-aff{border-color:rgba(168,85,247,.38);background:rgba(168,85,247,.04)}
.up-ico{font-size:1.35rem;margin-bottom:3px}
.up-nm{font-size:.7rem;font-weight:700;margin-bottom:2px}
.up-dsc{font-size:.6rem;color:var(--muted);line-height:1.3;margin-bottom:5px}
.up-cost{font-family:var(--font-m);font-size:.66rem;color:var(--gold)}
.up-card.up-b .up-cost{color:var(--green)}

/* ── Achievement card ── */
.ach-card{
  width:148px;flex-shrink:0;background:var(--surface2);border:1px solid var(--border);
  border-radius:6px;padding:9px;
}
.ach-card.ach-u{border-color:rgba(251,191,36,.22);background:rgba(251,191,36,.03)}
.ach-card.ach-l{opacity:.3;filter:grayscale(.7)}
.ach-ico{font-size:1.35rem;margin-bottom:3px}
.ach-nm{font-size:.7rem;font-weight:700;margin-bottom:2px}
.ach-dsc{font-size:.6rem;color:var(--muted);line-height:1.3}

/* ── Prestige shop card ── */
.pu-card{
  width:178px;flex-shrink:0;background:var(--surface2);border:1px solid rgba(251,191,36,.14);
  border-radius:6px;padding:9px;cursor:pointer;transition:all .18s;
}
.pu-card:hover:not(.pu-b):not(.pu-l){border-color:var(--gold);box-shadow:0 0 14px rgba(251,191,36,.3);transform:translateY(-2px)}
.pu-card.pu-b{opacity:.48;cursor:default;border-color:rgba(52,211,153,.18)}
.pu-card.pu-l{opacity:.22;cursor:not-allowed;filter:grayscale(.7)}
.pu-ico{font-size:1.35rem;margin-bottom:3px}
.pu-nm{font-size:.7rem;font-weight:700;margin-bottom:2px}
.pu-dsc{font-size:.6rem;color:var(--muted);line-height:1.3;margin-bottom:5px}
.pu-cost{font-family:var(--font-m);font-size:.66rem;color:var(--gold)}
.pu-card.pu-b .pu-cost{color:var(--green)}

/* ── Notification ── */
#notif{
  position:fixed;bottom:234px;right:18px;width:255px;
  background:linear-gradient(135deg,rgba(12,17,32,.97),rgba(21,30,46,.97));
  border:1px solid var(--border2);border-left:3px solid var(--purple);
  border-radius:8px;padding:11px 13px;z-index:999;
  transform:translateX(125%);transition:transform .38s cubic-bezier(.34,1.56,.64,1);
  box-shadow:0 8px 30px rgba(0,0,0,.55),0 0 20px rgba(168,85,247,.2);
  pointer-events:none;
}
#notif.show{transform:translateX(0)}
.n-head{font-family:var(--font-d);font-size:.52rem;letter-spacing:2px;color:var(--purple);text-transform:uppercase;margin-bottom:3px}
.n-body{font-size:.8rem;font-weight:500}

/* ── Prestige modal ── */
#p-modal{display:none;position:fixed;inset:0;background:rgba(3,4,8,.88);z-index:2000;align-items:center;justify-content:center;backdrop-filter:blur(5px)}
#p-modal.show{display:flex}
.m-box{
  background:linear-gradient(155deg,rgba(12,17,32,.99),rgba(6,10,18,.99));
  border:1px solid var(--border2);border-radius:14px;padding:30px 34px;
  max-width:400px;width:90%;
  box-shadow:0 0 80px rgba(168,85,247,.22),0 30px 60px rgba(0,0,0,.85);
  text-align:center;position:relative;overflow:hidden;
}
.m-box::before{content:'';position:absolute;inset:0;background:radial-gradient(ellipse at 50% 0%,rgba(168,85,247,.07),transparent 60%);pointer-events:none}
.m-title{font-family:var(--font-d);font-size:1.35rem;font-weight:900;letter-spacing:3px;text-transform:uppercase;background:linear-gradient(90deg,var(--gold),var(--purple));-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;margin-bottom:11px}
.m-desc{font-size:.83rem;color:var(--muted);line-height:1.65;margin-bottom:18px}
.m-gain{background:rgba(251,191,36,.07);border:1px solid rgba(251,191,36,.22);border-radius:7px;padding:13px;margin-bottom:20px}
.m-glbl{font-family:var(--font-d);font-size:.5rem;letter-spacing:2px;color:var(--muted);text-transform:uppercase;margin-bottom:3px}
.m-gval{font-family:var(--font-m);font-size:1.55rem;color:var(--gold);text-shadow:0 0 18px rgba(251,191,36,.45)}
.m-btns{display:flex;gap:11px;justify-content:center}
.m-btn{padding:9px 26px;border-radius:5px;border:none;font-family:var(--font-d);font-size:.58rem;font-weight:700;letter-spacing:2px;text-transform:uppercase;cursor:pointer;transition:all .2s}
.m-btn.cancel{background:var(--surface2);border:1px solid var(--border);color:var(--muted)}
.m-btn.cancel:hover{color:var(--text);border-color:var(--muted)}
.m-btn.confirm{background:linear-gradient(135deg,rgba(124,58,237,.8),rgba(79,70,229,.8));border:1px solid var(--purple);color:#fff;box-shadow:0 0 18px rgba(168,85,247,.4)}
.m-btn.confirm:hover{transform:translateY(-2px);box-shadow:0 0 28px rgba(168,85,247,.6),0 8px 20px rgba(0,0,0,.4)}

/* ── Click effects ── */
.float-n{position:absolute;font-family:var(--font-m);font-size:.82rem;font-weight:bold;color:var(--cyan);text-shadow:0 0 10px rgba(34,211,238,.5);pointer-events:none;animation:fltUp 1s ease-out forwards;z-index:100;white-space:nowrap}
@keyframes fltUp{0%{opacity:1;transform:translateY(0) scale(1)}30%{opacity:1;transform:translateY(-22px) scale(1.12)}100%{opacity:0;transform:translateY(-65px) scale(.85)}}
.click-p{position:absolute;width:4px;height:4px;border-radius:50%;pointer-events:none;animation:pfly .7s ease-out forwards}
@keyframes pfly{0%{opacity:1;transform:translate(0,0) scale(1)}100%{opacity:0;transform:translate(var(--dx),var(--dy)) scale(.1)}}
.p-ring{position:absolute;border-radius:50%;border:1.5px solid rgba(168,85,247,.55);pointer-events:none;animation:rexp .85s ease-out forwards}
@keyframes rexp{0%{width:60px;height:60px;margin-left:-30px;margin-top:-30px;opacity:.9}100%{width:260px;height:260px;margin-left:-130px;margin-top:-130px;opacity:0}}
</style>
</head>
<body>
<canvas id="sf"></canvas>
<div id="app">

  <header>
    <div class="h-title">
      <div class="h-dot"></div>
      <h1>Quantum Singularity</h1>
    </div>
    <div class="h-right">
      <span class="save-lbl" id="save-lbl">AUTOSAVE ON</span>
      <button id="prestige-btn" disabled>💥 BIG BANG</button>
    </div>
  </header>

  <div id="main">
    <!-- LEFT: Resources -->
    <div class="panel">
      <div class="p-head">Quantum State</div>
      <div class="p-scroll">
        <div id="ess-blk" class="ess-block" style="display:none">
          <div class="ess-lbl">✨ Cosmic Essence</div>
          <div class="ess-val" id="ess-val">0</div>
          <div class="ess-bonus" id="ess-bonus">+0% all production</div>
        </div>
        <div id="r-tiers"></div>
        <div class="stats-blk">
          <div class="stat-row"><span class="stat-lbl">Total Produced</span><span class="stat-v" id="s-total">0</span></div>
          <div class="stat-row"><span class="stat-lbl">Click Power</span><span class="stat-v" id="s-click">1</span></div>
          <div class="stat-row"><span class="stat-lbl">Production/s</span><span class="stat-v" id="s-qps">0</span></div>
          <div class="stat-row"><span class="stat-lbl">Big Bangs</span><span class="stat-v" id="s-prestige">0</span></div>
          <div class="stat-row"><span class="stat-lbl">Total Clicks</span><span class="stat-v" id="s-clicks">0</span></div>
        </div>
      </div>
    </div>

    <!-- CENTER: Singularity -->
    <div id="ctr">
      <div class="s-wrap" id="s-wrap">
        <div class="halo2"></div>
        <div class="halo1"></div>
        <button id="sbtn">
          <div class="btn-c">
            <div class="btn-em">🌀</div>
            <div class="btn-lbl">Singularity</div>
            <div class="btn-pw" id="btn-pw">+1 quark</div>
          </div>
        </button>
        <div class="fx" id="fx"></div>
      </div>
      <div class="prod-info">
        <div class="prod-qps" id="c-qps">0</div>
        <div class="prod-lbl">quarks per second</div>
      </div>
      <div class="ms-wrap">
        <div class="ms-head">
          <span class="ms-name" id="ms-name">Next milestone</span>
          <span class="ms-pct" id="ms-pct">0%</span>
        </div>
        <div class="ms-track"><div class="ms-fill" id="ms-fill" style="width:0%"></div></div>
      </div>
    </div>

    <!-- RIGHT: Generators -->
    <div class="panel">
      <div class="p-head">Generators</div>
      <div class="buy-tog">
        <button class="buy-btn act" data-n="1">×1</button>
        <button class="buy-btn" data-n="10">×10</button>
        <button class="buy-btn" data-n="100">×100</button>
        <button class="buy-btn" data-n="max">Max</button>
      </div>
      <div class="p-scroll" id="gen-list"></div>
    </div>
  </div>

  <!-- BOTTOM TABS -->
  <div id="bot">
    <div class="tab-bar">
      <button class="tab-btn act" data-tab="upgrades">Upgrades</button>
      <button class="tab-btn" data-tab="achievements">Achievements</button>
      <button class="tab-btn" data-tab="prestige-shop">Prestige Shop</button>
    </div>
    <div class="tab-pane act" id="tab-upgrades"></div>
    <div class="tab-pane" id="tab-achievements"></div>
    <div class="tab-pane" id="tab-prestige-shop"></div>
  </div>
</div>

<div id="notif">
  <div class="n-head" id="n-head">Achievement</div>
  <div class="n-body" id="n-body">Message</div>
</div>

<div id="p-modal">
  <div class="m-box">
    <div class="m-title">💥 Big Bang</div>
    <div class="m-desc">
      Collapse this universe and ignite a new one.<br>
      Your quarks and generators reset — but you gain permanent <strong style="color:var(--gold)">Cosmic Essence</strong>.
    </div>
    <div class="m-gain">
      <div class="m-glbl">You will receive</div>
      <div class="m-gval" id="m-gval">+0 ✨</div>
    </div>
    <div class="m-btns">
      <button class="m-btn cancel" id="m-cancel">Cancel</button>
      <button class="m-btn confirm" id="m-confirm">Ignite! 💥</button>
    </div>
  </div>
</div>

<script>
// ════════════════════════════════════════════════════════
//  DATA
// ════════════════════════════════════════════════════════

const TIERS = [
  {name:'Quarks',    icon:'⚛️',  th:0     },
  {name:'Particles', icon:'💫',  th:1e3   },
  {name:'Atoms',     icon:'🔬',  th:1e6   },
  {name:'Molecules', icon:'🧬',  th:1e9   },
  {name:'Stars',     icon:'⭐',  th:1e12  },
  {name:'Planets',   icon:'🪐',  th:1e15  },
  {name:'Galaxies',  icon:'🌌',  th:1e18  },
  {name:'Universes', icon:'🌐',  th:1e21  },
];

const GENS = [
  {id:'osc',  name:'Quark Oscillator', icon:'🌀', desc:'Vibrates quantum foam',          bc:10,     bp:0.1,    m:1.15},
  {id:'lens', name:'Particle Lens',    icon:'⚡', desc:'Focuses quantum fields',         bc:100,    bp:0.5,    m:1.15},
  {id:'reac', name:'Fusion Reactor',   icon:'🔥', desc:'Fuses particles into energy',   bc:1100,   bp:4,      m:1.15},
  {id:'weav', name:'Molecular Weaver', icon:'🕸️', desc:'Weaves quantum threads',         bc:12000,  bp:30,     m:1.15},
  {id:'star', name:'Stellar Forge',    icon:'⭐', desc:'Ignites stellar cores',          bc:130000, bp:250,    m:1.15},
  {id:'plan', name:'Planetary Engine', icon:'🪐', desc:'Spins worlds into being',        bc:1.4e6,  bp:2000,   m:1.15},
  {id:'gal',  name:'Galactic Weaver',  icon:'🌌', desc:'Knits galaxies together',        bc:2e7,    bp:16000,  m:1.15},
  {id:'cos',  name:'Cosmic Engine',    icon:'🌐', desc:'Breathes life into universes',   bc:3.3e8,  bp:130000, m:1.15},
];

const UPGRADES = [
  // click
  {id:'c1',icon:'👆',name:'Better Fingers',     desc:'Click power ×2',   cost:50,    eff:{t:'click',x:2},  req:{tq:25}       },
  {id:'c2',icon:'✨',name:'Quantum Touch',      desc:'Click power ×5',   cost:500,   eff:{t:'click',x:5},  req:{tq:200}      },
  {id:'c3',icon:'💥',name:'Dimensional Strike', desc:'Click power ×10',  cost:50000, eff:{t:'click',x:10}, req:{tq:10000}    },
  {id:'c4',icon:'🔱',name:'Reality Fracture',   desc:'Click power ×20',  cost:5e6,   eff:{t:'click',x:20}, req:{tq:1e6}      },
  {id:'c5',icon:'👊',name:'Cosmic Fist',        desc:'Click power ×50',  cost:5e9,   eff:{t:'click',x:50}, req:{tq:1e9}      },
  // per-gen
  {id:'g1',icon:'〰️',name:'Fast Vibration',    desc:'Oscillators ×2',   cost:200,   eff:{t:'gen',id:'osc', x:2}, req:{gen:{osc:5}}  },
  {id:'g2',icon:'📡',name:'Resonance Amp',     desc:'Oscillators ×3',   cost:2000,  eff:{t:'gen',id:'osc', x:3}, req:{gen:{osc:10}} },
  {id:'g3',icon:'🔊',name:'Quantum Resonance', desc:'Oscillators ×5',   cost:200000,eff:{t:'gen',id:'osc', x:5}, req:{gen:{osc:25}} },
  {id:'g4',icon:'🔭',name:'Lens Polish',       desc:'Lenses ×2',        cost:2000,  eff:{t:'gen',id:'lens',x:2}, req:{gen:{lens:5}} },
  {id:'g5',icon:'🎯',name:'Focus Beam',         desc:'Lenses ×3',        cost:20000, eff:{t:'gen',id:'lens',x:3}, req:{gen:{lens:10}}},
  {id:'g6',icon:'💫',name:'Quantum Focus',      desc:'Lenses ×5',        cost:2e6,   eff:{t:'gen',id:'lens',x:5}, req:{gen:{lens:25}}},
  {id:'g7',icon:'♨️',name:'Plasma Temp+',      desc:'Reactors ×2',      cost:20000, eff:{t:'gen',id:'reac',x:2}, req:{gen:{reac:5}} },
  {id:'g8',icon:'🔥',name:'Fusion Mastery',    desc:'Reactors ×3',      cost:200000,eff:{t:'gen',id:'reac',x:3}, req:{gen:{reac:10}}},
  {id:'g9',icon:'☢️',name:'Core Ignition',     desc:'Reactors ×5',      cost:2e7,   eff:{t:'gen',id:'reac',x:5}, req:{gen:{reac:25}}},
  {id:'ga',icon:'🕸️',name:'Silken Threads',    desc:'Weavers ×2',       cost:200000,eff:{t:'gen',id:'weav',x:2}, req:{gen:{weav:5}} },
  {id:'gb',icon:'🧵',name:'Weave Mastery',     desc:'Weavers ×5',       cost:2e7,   eff:{t:'gen',id:'weav',x:5}, req:{gen:{weav:15}}},
  {id:'gc',icon:'✨',name:'Brighter Stars',     desc:'Stellar ×2',       cost:2e6,   eff:{t:'gen',id:'star',x:2}, req:{gen:{star:5}} },
  {id:'gd',icon:'💫',name:'Supernova',          desc:'Stellar ×5',       cost:2e8,   eff:{t:'gen',id:'star',x:5}, req:{gen:{star:15}}},
  // global
  {id:'gl1',icon:'⬛',name:'Dark Matter',   desc:'All generators ×2',  cost:1e7,  eff:{t:'global',x:2},  req:{tq:5e6} },
  {id:'gl2',icon:'🌑',name:'Dark Energy',   desc:'All generators ×5',  cost:1e10, eff:{t:'global',x:5},  req:{tq:5e9} },
  {id:'gl3',icon:'🕳️',name:'Vacuum Energy', desc:'All generators ×10', cost:1e13, eff:{t:'global',x:10}, req:{tq:5e12}},
  {id:'gl4',icon:'🌊',name:'Higgs Field',   desc:'All generators ×25', cost:1e16, eff:{t:'global',x:25}, req:{tq:5e15}},
];

const ACHIEVEMENTS = [
  {id:'a1', icon:'⚛️',name:'First Spark',      desc:'Produce your first quark',          req:{tq:1}      },
  {id:'a2', icon:'💫',name:'Particle Flux',     desc:'Reach 1,000 total quarks',          req:{tq:1e3}    },
  {id:'a3', icon:'🔬',name:'Atomic Age',        desc:'Reach 1 million total quarks',      req:{tq:1e6}    },
  {id:'a4', icon:'🧬',name:'Molecular Dawn',    desc:'Reach 1 billion total quarks',      req:{tq:1e9}    },
  {id:'a5', icon:'⭐',name:'Stellar Fire',      desc:'Reach 1 trillion total quarks',     req:{tq:1e12}   },
  {id:'a6', icon:'🪐',name:'Planetary Scale',   desc:'Reach 1 quadrillion quarks',        req:{tq:1e15}   },
  {id:'a7', icon:'🌌',name:'Galactic Horizon',  desc:'Reach 1 quintillion quarks',        req:{tq:1e18}   },
  {id:'a8', icon:'⚙️',name:'First Machine',     desc:'Buy your first generator',          req:{gt:1}      },
  {id:'a9', icon:'🏭',name:'Factory Floor',     desc:'Own 10 generators total',           req:{gt:10}     },
  {id:'a10',icon:'🏙️',name:'Megacomplex',       desc:'Own 100 generators total',          req:{gt:100}    },
  {id:'a11',icon:'🌞',name:'Dyson Sphere',      desc:'Own 500 generators total',          req:{gt:500}    },
  {id:'a12',icon:'👆',name:'Click Newbie',      desc:'Click 100 times',                   req:{cl:100}    },
  {id:'a13',icon:'✌️',name:'Click Veteran',     desc:'Click 1,000 times',                req:{cl:1000}   },
  {id:'a14',icon:'🤚',name:'Click Master',      desc:'Click 10,000 times',               req:{cl:10000}  },
  {id:'a15',icon:'💥',name:'Big Banger',        desc:'Perform your first Big Bang',       req:{pr:1}      },
  {id:'a16',icon:'🔮',name:'Multiverse',        desc:'Perform 5 Big Bangs',              req:{pr:5}      },
  {id:'a17',icon:'✨',name:'Essence Hoarder',   desc:'Collect 10 Cosmic Essence total',   req:{te:10}     },
  {id:'a18',icon:'⚡',name:'Speed of Light',    desc:'Reach 1,000 quarks/sec',           req:{qps:1e3}   },
  {id:'a19',icon:'🚀',name:'Hyperdrive',        desc:'Reach 1 million quarks/sec',        req:{qps:1e6}   },
  {id:'a20',icon:'🌐',name:'Universe Engine',   desc:'Reach 1 billion quarks/sec',        req:{qps:1e9}   },
];

const P_UPGRADES = [
  {id:'pu1',icon:'🧠',name:'Quantum Memory',   desc:'Start with 10 Oscillators each Bang', cost:1 },
  {id:'pu2',icon:'🌊',name:'Residual Fields',  desc:'Click power ×3 permanently',          cost:2 },
  {id:'pu3',icon:'⬛',name:'Dark Momentum',    desc:'All generators ×2 permanently',       cost:3 },
  {id:'pu4',icon:'⏰',name:'Time Dilation',    desc:'50% offline production efficiency',   cost:5 },
  {id:'pu5',icon:'🔗',name:'Entanglement',     desc:'All generators ×5 permanently',       cost:10},
  {id:'pu6',icon:'📢',name:'Cosmic Amplifier', desc:'Click power ×10 permanently',         cost:15},
  {id:'pu7',icon:'🔮',name:'Parallel Worlds',  desc:'All generators ×10 permanently',      cost:25},
  {id:'pu8',icon:'🌀',name:'Singularity Core', desc:'All production ×25',                  cost:50},
];

const MILESTONES = [
  {name:'Particles',  v:1e3 },
  {name:'Atoms',      v:1e6 },
  {name:'Molecules',  v:1e9 },
  {name:'Stars',      v:1e12},
  {name:'Planets',    v:1e15},
  {name:'Galaxies',   v:1e18},
  {name:'Universes',  v:1e21},
];

// ════════════════════════════════════════════════════════
//  STATE
// ════════════════════════════════════════════════════════

let S = {
  q:0, tq:0, cl:0, pr:0, ess:0, te:0,
  g:{}, up:{}, ach:{}, pu:{},
  lastSave: Date.now(), lastTick: Date.now(),
};
GENS.forEach(g => S.g[g.id] = 0);

let buyAmt = 1;
let qps = 0;
let frame = 0;
let lastSaveTime = Date.now();
let tierEls = [];

// ════════════════════════════════════════════════════════
//  MATH
// ════════════════════════════════════════════════════════

function fmt(n) {
  if (n < 0) return '-' + fmt(-n);
  if (n < 1)    return n < 0.01 ? '0' : n.toFixed(2);
  if (n < 1e3)  return Math.floor(n).toString();
  if (n < 1e6)  return (n/1e3).toFixed(2)+'K';
  if (n < 1e9)  return (n/1e6).toFixed(2)+'M';
  if (n < 1e12) return (n/1e9).toFixed(2)+'B';
  if (n < 1e15) return (n/1e12).toFixed(2)+'T';
  if (n < 1e18) return (n/1e15).toFixed(2)+'Qa';
  if (n < 1e21) return (n/1e18).toFixed(2)+'Qi';
  if (n < 1e24) return (n/1e21).toFixed(2)+'Sx';
  if (n < 1e27) return (n/1e24).toFixed(2)+'Sp';
  return n.toExponential(2);
}

// Cost of buying 1 generator when `owned` are already owned
function costOne(g, owned) {
  return Math.ceil(g.bc * Math.pow(g.m, owned));
}

// Cost of buying n generators starting from `owned`
function costN(g, owned, n) {
  if (n <= 0) return 0;
  const base = g.bc * Math.pow(g.m, owned);
  return Math.ceil(base * (Math.pow(g.m, n) - 1) / (g.m - 1));
}

// Max affordable given current quarks
function maxAffordable(g) {
  const owned = S.g[g.id];
  const base = g.bc * Math.pow(g.m, owned);
  if (base > S.q) return 0;
  return Math.max(0, Math.floor(Math.log(S.q * (g.m - 1) / base + 1) / Math.log(g.m)));
}

function effectiveN(g) {
  return buyAmt === 'max' ? maxAffordable(g) : buyAmt;
}

function clickPow() {
  let p = 1;
  UPGRADES.forEach(u => { if (S.up[u.id] && u.eff.t === 'click') p *= u.eff.x; });
  if (S.pu['pu2']) p *= 3;
  if (S.pu['pu6']) p *= 10;
  return p;
}

function genMult(gid) {
  let m = 1;
  UPGRADES.forEach(u => {
    if (!S.up[u.id]) return;
    if (u.eff.t === 'gen' && u.eff.id === gid) m *= u.eff.x;
    if (u.eff.t === 'global') m *= u.eff.x;
  });
  if (S.pu['pu3']) m *= 2;
  if (S.pu['pu5']) m *= 5;
  if (S.pu['pu7']) m *= 10;
  if (S.pu['pu8']) m *= 25;
  m *= (1 + S.ess * 0.05);
  return m;
}

function calcQps() {
  let t = 0;
  GENS.forEach(g => { if (S.g[g.id] > 0) t += S.g[g.id] * g.bp * genMult(g.id); });
  return t;
}

function genTotal() { return Object.values(S.g).reduce((a,b)=>a+b,0); }

function essGain() { return Math.floor(Math.sqrt(S.tq / 1e6)); }

function canPrestige() { return S.tq >= 1e9; }

function upReqMet(u) {
  const r = u.req;
  if (r.tq !== undefined && S.tq < r.tq) return false;
  if (r.gen) for (const [id,n] of Object.entries(r.gen)) if ((S.g[id]||0) < n) return false;
  return true;
}

// ════════════════════════════════════════════════════════
//  ACTIONS
// ════════════════════════════════════════════════════════

function doClick(e) {
  const p = clickPow();
  S.q += p; S.tq += p; S.cl++;
  spawnFx(e, p);
}

function buyGen(gid) {
  const g = GENS.find(x=>x.id===gid);
  if (!g) return;
  const n = effectiveN(g);
  if (n <= 0) return;
  const cost = costN(g, S.g[g.id], n);
  if (S.q < cost) return;
  S.q -= cost;
  S.g[g.id] += n;
}

function buyUp(uid) {
  if (S.up[uid]) return;
  const u = UPGRADES.find(x=>x.id===uid);
  if (!u || !upReqMet(u) || S.q < u.cost) return;
  S.q -= u.cost;
  S.up[uid] = true;
  notify('Upgrade Purchased', `${u.name}: ${u.desc}`);
}

function buyPUp(pid) {
  if (S.pu[pid]) return;
  const pu = P_UPGRADES.find(x=>x.id===pid);
  if (!pu || S.ess < pu.cost) return;
  S.ess -= pu.cost;
  S.pu[pid] = true;
  notify('✨ Prestige Upgrade', `${pu.name}: ${pu.desc}`);
}

function openPrestige() {
  if (!canPrestige()) return;
  document.getElementById('m-gval').textContent = `+${essGain()} ✨ Cosmic Essence`;
  document.getElementById('p-modal').classList.add('show');
}

function doPrestige() {
  const gain = essGain();
  S.ess += gain; S.te += gain; S.pr++;
  S.q = 0; S.tq = 0;
  GENS.forEach(g => S.g[g.id] = 0);
  S.up = {};
  if (S.pu['pu1']) S.g['osc'] = 10;
  document.getElementById('p-modal').classList.remove('show');
  if (S.ess > 0) document.getElementById('ess-blk').style.display = '';
  notify('💥 Big Bang!', `Universe collapsed! Gained +${gain} Cosmic Essence.`);
}

// ════════════════════════════════════════════════════════
//  ACHIEVEMENTS
// ════════════════════════════════════════════════════════

function checkAch() {
  ACHIEVEMENTS.forEach(a => {
    if (S.ach[a.id]) return;
    const r = a.req;
    let met = false;
    if (r.tq  !== undefined && S.tq         >= r.tq)  met = true;
    if (r.gt  !== undefined && genTotal()    >= r.gt)  met = true;
    if (r.cl  !== undefined && S.cl         >= r.cl)  met = true;
    if (r.pr  !== undefined && S.pr         >= r.pr)  met = true;
    if (r.te  !== undefined && S.te         >= r.te)  met = true;
    if (r.qps !== undefined && qps          >= r.qps) met = true;
    if (met) { S.ach[a.id] = true; notify(`🏆 ${a.name}`, a.desc); }
  });
}

// ════════════════════════════════════════════════════════
//  SAVE / LOAD
// ════════════════════════════════════════════════════════

const SK = 'qs_v3';

function save() {
  try {
    S.lastSave = Date.now();
    localStorage.setItem(SK, JSON.stringify(S));
    const d = new Date();
    document.getElementById('save-lbl').textContent =
      `SAVED ${d.getHours().toString().padStart(2,'0')}:${d.getMinutes().toString().padStart(2,'0')}`;
  } catch(e) {}
}

function load() {
  try {
    const raw = localStorage.getItem(SK);
    if (!raw) return;
    const sv = JSON.parse(raw);
    S.q   = sv.q   || 0;
    S.tq  = sv.tq  || 0;
    S.cl  = sv.cl  || 0;
    S.pr  = sv.pr  || 0;
    S.ess = sv.ess || 0;
    S.te  = sv.te  || 0;
    S.lastSave = sv.lastSave || Date.now();
    if (sv.g)  Object.assign(S.g,  sv.g);
    if (sv.up) Object.assign(S.up, sv.up);
    if (sv.ach)Object.assign(S.ach,sv.ach);
    if (sv.pu) Object.assign(S.pu, sv.pu);

    // Offline progress
    if (S.pu['pu4']) {
      const secs = Math.min((Date.now() - S.lastSave) / 1000, 8*3600);
      if (secs > 30) {
        const earned = calcQps() * secs * 0.5;
        if (earned > 0) {
          S.q += earned; S.tq += earned;
          setTimeout(() => notify('⏰ Offline Progress', `Gained ${fmt(earned)} quarks while away!`), 900);
        }
      }
    }

    if (S.ess > 0 || S.pr > 0) document.getElementById('ess-blk').style.display = '';
  } catch(e) { console.error('Load failed', e); }
}

// ════════════════════════════════════════════════════════
//  NOTIFICATIONS
// ════════════════════════════════════════════════════════

let nq = [], nActive = false;

function notify(head, body) {
  nq.push({head,body});
  if (!nActive) showNotif();
}

function showNotif() {
  if (!nq.length) { nActive = false; return; }
  nActive = true;
  const {head,body} = nq.shift();
  document.getElementById('n-head').textContent = head;
  document.getElementById('n-body').textContent = body;
  const el = document.getElementById('notif');
  el.classList.add('show');
  setTimeout(() => { el.classList.remove('show'); setTimeout(showNotif, 420); }, 3000);
}

// ════════════════════════════════════════════════════════
//  CLICK EFFECTS
// ════════════════════════════════════════════════════════

const PCOLS = ['#a855f7','#60a5fa','#22d3ee','#34d399','#fbbf24','#f87171'];

function spawnFx(e, power) {
  const wrap = document.getElementById('s-wrap');
  const layer = document.getElementById('fx');
  const r = wrap.getBoundingClientRect();
  const cx = (e?.clientX || r.left + r.width/2) - r.left;
  const cy = (e?.clientY || r.top  + r.height/2) - r.top;

  // Floating number
  const n = document.createElement('div');
  n.className = 'float-n';
  n.textContent = '+' + fmt(power);
  n.style.left = (cx + (Math.random()-.5)*50) + 'px';
  n.style.top  = (cy - 8) + 'px';
  layer.appendChild(n);
  setTimeout(() => n.remove(), 1050);

  // Burst particles
  for (let i = 0; i < 8; i++) {
    const ang = (i/8)*Math.PI*2 + Math.random()*.7;
    const dist = 55 + Math.random()*55;
    const p = document.createElement('div');
    p.className = 'click-p';
    p.style.cssText = `left:${cx}px;top:${cy}px;background:${PCOLS[i%PCOLS.length]};box-shadow:0 0 5px currentColor;--dx:${Math.cos(ang)*dist}px;--dy:${Math.sin(ang)*dist}px`;
    layer.appendChild(p);
    setTimeout(() => p.remove(), 750);
  }

  // Ring
  const ring = document.createElement('div');
  ring.className = 'p-ring';
  ring.style.left = cx + 'px';
  ring.style.top  = cy + 'px';
  layer.appendChild(ring);
  setTimeout(() => ring.remove(), 900);
}

// ════════════════════════════════════════════════════════
//  STARFIELD
// ════════════════════════════════════════════════════════

function initStarfield() {
  const c = document.getElementById('sf');
  const ctx = c.getContext('2d');
  const resize = () => { c.width = innerWidth; c.height = innerHeight; };
  resize();
  window.addEventListener('resize', resize);

  const stars = Array.from({length:230}, () => ({
    x: Math.random()*innerWidth, y: Math.random()*innerHeight,
    r: Math.random()*1.5+.3,
    base: Math.random()*.65+.15,
    ph: Math.random()*Math.PI*2,
    spd: Math.random()*.018+.003,
  }));

  const nebulae = [
    {x:innerWidth*.2, y:innerHeight*.3, r:150, col:'rgba(168,85,247,.025)'},
    {x:innerWidth*.8, y:innerHeight*.7, r:120, col:'rgba(96,165,250,.02)'},
    {x:innerWidth*.6, y:innerHeight*.2, r:100, col:'rgba(34,211,238,.018)'},
    {x:innerWidth*.1, y:innerHeight*.8, r:130, col:'rgba(124,58,237,.022)'},
  ];

  (function draw() {
    ctx.clearRect(0,0,c.width,c.height);
    nebulae.forEach(nb => {
      const grd = ctx.createRadialGradient(nb.x,nb.y,0,nb.x,nb.y,nb.r);
      grd.addColorStop(0,nb.col); grd.addColorStop(1,'transparent');
      ctx.fillStyle = grd;
      ctx.beginPath(); ctx.arc(nb.x,nb.y,nb.r,0,Math.PI*2); ctx.fill();
    });
    stars.forEach(s => {
      s.ph += s.spd;
      const op = s.base + .22*Math.sin(s.ph);
      ctx.beginPath(); ctx.arc(s.x,s.y,s.r,0,Math.PI*2);
      ctx.fillStyle = `rgba(210,225,255,${op})`; ctx.fill();
    });
    requestAnimationFrame(draw);
  })();
}

// ════════════════════════════════════════════════════════
//  RENDER
// ════════════════════════════════════════════════════════

function renderResources() {
  const container = document.getElementById('r-tiers');
  if (tierEls.length === 0) {
    TIERS.forEach((t,i) => {
      const el = document.createElement('div');
      el.className = 'r-tier';
      el.id = 'rt'+i;
      el.innerHTML = `
        <div class="r-left">
          <span class="r-ico">${t.icon}</span>
          <span class="r-name">${t.name}</span>
        </div>
        <div class="r-right">
          <div class="r-val" id="rv${i}">0</div>
          <div class="r-rate" id="rr${i}"></div>
        </div>`;
      container.appendChild(el);
      tierEls.push(el);
    });
    tierEls[0].classList.add('vis');
  }

  TIERS.forEach((t,i) => {
    const show = i===0 || S.tq >= t.th * 0.005;
    if (show && !tierEls[i].classList.contains('vis')) tierEls[i].classList.add('vis');
    if (tierEls[i].classList.contains('vis')) {
      const val = i===0 ? S.q : S.q / t.th;
      const rate = i===0 ? qps : qps / t.th;
      document.getElementById('rv'+i).textContent = fmt(val);
      document.getElementById('rr'+i).textContent = qps > 0 ? `+${fmt(rate)}/s` : '';
    }
  });

  // Essence
  if (S.ess > 0 || S.pr > 0) {
    document.getElementById('ess-blk').style.display = '';
    document.getElementById('ess-val').textContent = fmt(S.ess) + ' ✨';
    document.getElementById('ess-bonus').textContent = `+${(S.ess*5).toFixed(0)}% all production`;
  }

  // Stats
  document.getElementById('s-total').textContent   = fmt(S.tq);
  document.getElementById('s-click').textContent   = fmt(clickPow());
  document.getElementById('s-qps').textContent     = fmt(qps)+'/s';
  document.getElementById('s-prestige').textContent= S.pr;
  document.getElementById('s-clicks').textContent  = fmt(S.cl);
}

function renderCenter() {
  qps = calcQps();
  document.getElementById('c-qps').textContent  = fmt(qps);
  const cp = clickPow();
  document.getElementById('btn-pw').textContent = `+${fmt(cp)} quark${cp===1?'':'s'}`;

  // Milestone
  const next = MILESTONES.find(m => S.tq < m.v);
  if (next) {
    const idx = MILESTONES.indexOf(next);
    const prev = idx > 0 ? MILESTONES[idx-1].v : 0;
    const pct = Math.min(100, (S.tq - prev) / (next.v - prev) * 100);
    document.getElementById('ms-name').textContent = `Next: ${next.name}`;
    document.getElementById('ms-pct').textContent  = pct.toFixed(1)+'%';
    document.getElementById('ms-fill').style.width = pct+'%';
  } else {
    document.getElementById('ms-name').textContent = '🌌 All Milestones Reached!';
    document.getElementById('ms-pct').textContent  = '100%';
    document.getElementById('ms-fill').style.width = '100%';
  }

  // Prestige button
  const pb = document.getElementById('prestige-btn');
  if (canPrestige()) {
    pb.disabled = false;
    pb.textContent = `💥 BIG BANG (+${essGain()} ✨)`;
  } else {
    pb.disabled = true;
    pb.textContent = '💥 BIG BANG';
  }
}

function renderGens() {
  let html = '';
  GENS.forEach((g,i) => {
    const prev = GENS[i-1];
    const vis = !prev || S.g[prev.id] > 0 || S.tq >= g.bc * 0.25;
    if (!vis) return;
    const cnt = S.g[g.id];
    const n = effectiveN(g);
    const n1 = Math.max(1, n);
    const cost = n <= 0 ? costOne(g, cnt) : costN(g, cnt, n1);
    const aff = n > 0 && S.q >= cost;
    const pEa = g.bp * genMult(g.id);
    html += `
      <div class="gen ${aff?'gen-aff':''}" onclick="buyGen('${g.id}')">
        <div class="gen-top">
          <div class="gen-lft"><span class="gen-ico">${g.icon}</span><span class="gen-nm">${g.name}</span></div>
          <span class="gen-cnt">${cnt}</span>
        </div>
        <div class="gen-dsc">${g.desc}</div>
        <div class="gen-bot">
          <span class="gen-cost ${aff?'aff':''}">×${n1}${fmt(cost)} ⚛️</span>
          <span class="gen-prod">${cnt>0 ? fmt(cnt*pEa)+'/s' : fmt(pEa)+'/s ea.'}</span>
        </div>
      </div>`;
  });
  document.getElementById('gen-list').innerHTML = html ||
    '<div class="tab-empty" style="padding:14px">Produce more quarks to reveal generators...</div>';
}

function renderUps() {
  let html = '';
  UPGRADES.forEach(u => {
    const bought = S.up[u.id];
    const met = upReqMet(u);
    if (!bought && !met) return;
    const aff = !bought && met && S.q >= u.cost;
    let cls = 'up-card';
    if (bought) cls += ' up-b';
    else if (!met) cls += ' up-l';
    else if (aff) cls += ' up-aff';
    html += `
      <div class="${cls}" onclick="buyUp('${u.id}')">
        <div class="up-ico">${u.icon}</div>
        <div class="up-nm">${u.name}</div>
        <div class="up-dsc">${u.desc}</div>
        <div class="up-cost">${bought ? '✓ Owned' : fmt(u.cost)+' ⚛️'}</div>
      </div>`;
  });
  document.getElementById('tab-upgrades').innerHTML = html ||
    '<div class="tab-empty">Produce more quarks to unlock upgrades...</div>';
}

function renderAch() {
  document.getElementById('tab-achievements').innerHTML = ACHIEVEMENTS.map(a => {
    const u = S.ach[a.id];
    return `<div class="ach-card ${u?'ach-u':'ach-l'}">
      <div class="ach-ico">${a.icon}</div>
      <div class="ach-nm">${u ? a.name : '???'}</div>
      <div class="ach-dsc">${u ? a.desc : 'Keep playing...'}</div>
    </div>`;
  }).join('');
}

function renderPShop() {
  const tab = document.getElementById('tab-prestige-shop');
  if (S.pr === 0) {
    tab.innerHTML = '<div class="tab-empty">Perform your first Big Bang to unlock the Prestige Shop...</div>';
    return;
  }
  tab.innerHTML = P_UPGRADES.map(pu => {
    const bought = S.pu[pu.id];
    const aff = !bought && S.ess >= pu.cost;
    let cls = 'pu-card';
    if (bought) cls += ' pu-b';
    else if (!aff) cls += ' pu-l';
    return `<div class="${cls}" onclick="buyPUp('${pu.id}')">
      <div class="pu-ico">${pu.icon}</div>
      <div class="pu-nm">${pu.name}</div>
      <div class="pu-dsc">${pu.desc}</div>
      <div class="pu-cost">${bought ? '✓ Owned' : pu.cost+' ✨'}</div>
    </div>`;
  }).join('');
}

// ════════════════════════════════════════════════════════
//  GAME LOOP
// ════════════════════════════════════════════════════════

function tick() {
  const now = Date.now();
  const dt = Math.min((now - S.lastTick) / 1000, 1);
  S.lastTick = now;
  qps = calcQps();
  const earned = qps * dt;
  S.q += earned; S.tq += earned;
  checkAch();
}

function loop() {
  tick();
  frame++;
  renderResources();
  renderCenter();
  if (frame % 4  === 0) renderGens();
  if (frame % 18 === 0) { renderUps(); renderAch(); renderPShop(); }
  if (Date.now() - lastSaveTime > 30000) { lastSaveTime = Date.now(); save(); }
  requestAnimationFrame(loop);
}

// ════════════════════════════════════════════════════════
//  EVENTS
// ════════════════════════════════════════════════════════

function initEvents() {
  document.getElementById('sbtn').addEventListener('click', doClick);

  // Space bar to click
  document.addEventListener('keydown', e => {
    if (e.code === 'Space' && e.target === document.body) {
      e.preventDefault();
      doClick(null);
    }
  });

  // Buy toggle
  document.querySelectorAll('.buy-btn').forEach(btn => {
    btn.addEventListener('click', () => {
      document.querySelectorAll('.buy-btn').forEach(b => b.classList.remove('act'));
      btn.classList.add('act');
      buyAmt = btn.dataset.n === 'max' ? 'max' : parseInt(btn.dataset.n);
    });
  });

  // Tabs
  document.querySelectorAll('.tab-btn').forEach(btn => {
    btn.addEventListener('click', () => {
      document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('act'));
      document.querySelectorAll('.tab-pane').forEach(p => p.classList.remove('act'));
      btn.classList.add('act');
      document.getElementById('tab-' + btn.dataset.tab).classList.add('act');
    });
  });

  // Prestige
  document.getElementById('prestige-btn').addEventListener('click', openPrestige);
  document.getElementById('m-confirm').addEventListener('click', doPrestige);
  document.getElementById('m-cancel').addEventListener('click', () => {
    document.getElementById('p-modal').classList.remove('show');
  });

  // Save on exit
  window.addEventListener('beforeunload', save);
}

// ════════════════════════════════════════════════════════
//  INIT
// ════════════════════════════════════════════════════════

load();
initStarfield();
initEvents();
loop();
</script>
</body>
</html>