← back to Games Agentabrams

games/trivia-90210/90210Trivia.aa

576 lines

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>90210 Trivia — Beverly Hills Pop Quiz</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@600;700;900&family=Inter:wght@400;500;600;700&display=swap');

*{margin:0;padding:0;box-sizing:border-box;}
html{-webkit-text-size-adjust:100%;text-size-adjust:100%;height:100%;}
/* iOS / iPad touch hardening: no double-tap zoom, no 300ms delay,
   no grey tap-flash, no long-press callout on the answer tiles */
body{touch-action:manipulation;-webkit-tap-highlight-color:transparent;}
.opt,button,.btn{
  touch-action:manipulation;-webkit-tap-highlight-color:transparent;
  -webkit-user-select:none;user-select:none;-webkit-touch-callout:none;
}

:root{
  --ivory:#efe3c8; --ivory-dk:#c9b07a;
  --gold:#e9c46a; --gold-hi:#f6de9b; --peach:#f4a261; --burnt:#e76f51; --teal:#2a9d8f;
  --ink:#1a1410; --ink-soft:#2a211a;
  --green:#41c98a; --red:#e5604f;
  --font-disp:"Playfair Display", Georgia, serif;
  --font-body:"Inter", -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
}

html,body{height:100%;}
body{
  font-family:var(--font-body);
  color:var(--ivory);
  background:
    radial-gradient(circle at 18% 0%, rgba(233,196,106,.22), transparent 42%),
    radial-gradient(circle at 100% 100%, rgba(231,111,81,.20), transparent 46%),
    linear-gradient(160deg, #241a12 0%, #17110c 55%, #0d0907 100%);
  min-height:100%;
  display:flex; align-items:center; justify-content:center;
  padding:clamp(12px,3vw,28px);
  overflow:hidden;
}

.stage{
  width:min(560px, 100%);
  max-height:100%;
  display:flex; flex-direction:column;
}

/* ---- Card ---- */
.card{
  position:relative;
  background:
    linear-gradient(180deg, rgba(255,255,255,.05), rgba(0,0,0,.18)),
    linear-gradient(155deg, #2c2118, #1b140e);
  border:1px solid rgba(233,196,106,.35);
  border-radius:22px;
  padding:clamp(18px,4vw,30px);
  box-shadow:0 30px 70px rgba(0,0,0,.6), inset 0 1px 0 rgba(255,255,255,.06);
  overflow:hidden;
}
.card::before{ /* gold hairline frame */
  content:""; position:absolute; inset:8px; border:1px solid rgba(233,196,106,.18);
  border-radius:15px; pointer-events:none;
}

/* ---- Header ---- */
.head{ display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:14px; }
.brand{ display:flex; align-items:center; gap:9px; }
.brand .mark{
  font-size:20px; filter:drop-shadow(0 2px 4px rgba(0,0,0,.5));
}
.brand .zip{
  font-family:var(--font-disp); font-weight:900; letter-spacing:.02em;
  font-size:clamp(17px,4.5vw,22px);
  background:linear-gradient(180deg,var(--gold-hi),var(--peach));
  -webkit-background-clip:text; background-clip:text; -webkit-text-fill-color:transparent;
}
.brand .sub{ font-size:10px; letter-spacing:.28em; text-transform:uppercase; color:var(--ivory-dk); margin-top:2px; }
.hud{ display:flex; align-items:center; gap:10px; }
.pill{
  font-size:12px; font-weight:700; letter-spacing:.04em;
  padding:6px 11px; border-radius:999px;
  border:1px solid rgba(233,196,106,.4);
  background:linear-gradient(180deg, rgba(233,196,106,.16), rgba(0,0,0,.25));
  white-space:nowrap;
}
.pill .lab{ color:var(--ivory-dk); font-weight:600; font-size:10px; text-transform:uppercase; letter-spacing:.12em; margin-right:5px; }
.streak.hot{ border-color:var(--peach); box-shadow:0 0 16px rgba(244,162,97,.5); }

/* ---- Timer bar ---- */
.timer-wrap{ height:6px; border-radius:999px; background:rgba(0,0,0,.35); overflow:hidden; margin-bottom:16px; border:1px solid rgba(233,196,106,.14); }
.timer-bar{ height:100%; width:100%; transform-origin:left;
  background:linear-gradient(90deg,var(--gold),var(--peach),var(--burnt));
  transition:transform .1s linear, background .3s; }
.timer-bar.warn{ background:linear-gradient(90deg,var(--burnt),#c0392b); }

/* ---- Question ---- */
.qmeta{ font-size:11px; letter-spacing:.2em; text-transform:uppercase; color:var(--ivory-dk); margin-bottom:8px; }
.qmeta b{ color:var(--gold); }
.question{
  font-family:var(--font-disp); font-weight:700;
  font-size:clamp(19px,5vw,26px); line-height:1.22;
  margin-bottom:clamp(16px,3.5vw,22px); min-height:2.4em;
  display:flex; align-items:center;
}

/* ---- Options ---- */
.opts{ display:grid; gap:10px; }
.opt{
  position:relative; text-align:left; cursor:pointer;
  font-family:var(--font-body); font-size:clamp(14px,3.6vw,16px); font-weight:600; color:var(--ivory);
  padding:14px 16px 14px 48px; border-radius:13px;
  background:linear-gradient(160deg, rgba(255,255,255,.045), rgba(0,0,0,.14));
  border:1px solid rgba(233,196,106,.24);
  transition:transform .12s ease, border-color .18s, background .18s, box-shadow .18s;
}
.opt .key{
  position:absolute; left:12px; top:50%; transform:translateY(-50%);
  width:26px; height:26px; border-radius:8px;
  display:flex; align-items:center; justify-content:center;
  font-family:var(--font-disp); font-weight:700; font-size:13px; color:var(--ink);
  background:linear-gradient(180deg,var(--gold-hi),var(--ivory-dk));
}
.opt:hover:not(.locked){ transform:translateY(-2px); border-color:var(--gold); box-shadow:0 10px 24px rgba(0,0,0,.4); }
.opt:active:not(.locked){ transform:translateY(0) scale(.99); }
.opt.locked{ cursor:default; }
.opt.correct{ border-color:var(--green); background:linear-gradient(160deg, rgba(65,201,138,.28), rgba(65,201,138,.08)); box-shadow:0 0 22px rgba(65,201,138,.35); }
.opt.correct .key{ background:linear-gradient(180deg,#8ff0c2,var(--green)); }
.opt.wrong{ border-color:var(--red); background:linear-gradient(160deg, rgba(229,96,79,.24), rgba(229,96,79,.06)); }
.opt.wrong .key{ background:linear-gradient(180deg,#f2a397,var(--red)); }
.opt.dim{ opacity:.42; }
.opt .verdict{ position:absolute; right:14px; top:50%; transform:translateY(-50%); font-size:16px; opacity:0; transition:opacity .2s; }
.opt.correct .verdict, .opt.wrong .verdict{ opacity:1; }

.footline{ display:flex; align-items:center; justify-content:space-between; margin-top:14px; min-height:20px;
  font-size:12px; color:var(--ivory-dk); }
.footline .pts{ color:var(--gold); font-weight:700; }

/* ---- Buttons ---- */
.btn{
  font-family:var(--font-body); font-weight:700; font-size:14px; letter-spacing:.06em;
  color:var(--ink); cursor:pointer; border:none;
  padding:14px 26px; border-radius:999px;
  background:linear-gradient(180deg,var(--gold-hi),var(--peach));
  box-shadow:0 12px 28px rgba(0,0,0,.45); text-transform:uppercase;
  transition:transform .14s, box-shadow .14s, filter .14s;
}
.btn:hover{ transform:translateY(-2px); filter:brightness(1.06); }
.btn:active{ transform:translateY(0); }
.btn.ghost{ background:transparent; color:var(--ivory); border:1px solid rgba(233,196,106,.4); box-shadow:none; }
.btn.ghost:hover{ border-color:var(--gold); }

/* ---- Screens ---- */
.screen{ display:none; }
.screen.on{ display:block; animation:fade .4s ease both; }
@keyframes fade{ from{opacity:0; transform:translateY(10px);} to{opacity:1; transform:none;} }

/* Start screen */
.start{ text-align:center; padding:clamp(6px,2vw,14px) 0; }
.start .big{
  font-family:var(--font-disp); font-weight:900; line-height:.98;
  font-size:clamp(38px,11vw,64px);
  background:linear-gradient(180deg,var(--gold-hi) 0%, var(--peach) 70%, var(--burnt) 100%);
  -webkit-background-clip:text; background-clip:text; -webkit-text-fill-color:transparent;
  filter:drop-shadow(0 4px 10px rgba(0,0,0,.4));
  margin:6px 0 2px;
}
.start .kicker{ font-size:12px; letter-spacing:.34em; text-transform:uppercase; color:var(--ivory-dk); }
.start .tag{ font-family:var(--font-disp); font-style:italic; font-size:clamp(15px,4.2vw,19px); color:var(--ivory); margin:14px 0 6px; }
.start .blurb{ font-size:13px; color:var(--ivory-dk); max-width:38ch; margin:0 auto 22px; line-height:1.6; }
.start .row{ display:flex; gap:10px; justify-content:center; flex-wrap:wrap; }
.palms{ font-size:26px; letter-spacing:6px; margin:16px 0 4px; opacity:.9; }
.best-note{ font-size:12px; color:var(--gold); margin-top:16px; min-height:18px; letter-spacing:.04em; }

/* Result screen */
.result{ text-align:center; }
.result .rank{
  font-family:var(--font-disp); font-weight:900; font-size:clamp(26px,7vw,40px);
  background:linear-gradient(180deg,var(--gold-hi),var(--peach));
  -webkit-background-clip:text; background-clip:text; -webkit-text-fill-color:transparent;
  margin:4px 0 2px;
}
.result .rank-sub{ font-size:12px; letter-spacing:.24em; text-transform:uppercase; color:var(--ivory-dk); margin-bottom:18px; }
.scorecard{
  display:grid; grid-template-columns:repeat(3,1fr); gap:10px; margin:14px 0 22px;
}
.stat{
  background:linear-gradient(160deg, rgba(255,255,255,.05), rgba(0,0,0,.2));
  border:1px solid rgba(233,196,106,.28); border-radius:14px; padding:14px 8px;
}
.stat .n{ font-family:var(--font-disp); font-weight:900; font-size:clamp(22px,6vw,30px); color:var(--gold); }
.stat .l{ font-size:10px; letter-spacing:.14em; text-transform:uppercase; color:var(--ivory-dk); margin-top:4px; }
.new-best{ display:inline-block; font-size:11px; font-weight:700; letter-spacing:.14em; text-transform:uppercase;
  color:var(--ink); background:linear-gradient(180deg,var(--gold-hi),var(--peach));
  padding:4px 12px; border-radius:999px; margin-bottom:14px; }
</style>
</head>
<body>
<div class="stage">
  <div class="card">

    <!-- ===== START ===== -->
    <section class="screen on" id="scr-start">
      <div class="start">
        <div class="kicker">Beverly Hills Pop Quiz</div>
        <div class="big">90210</div>
        <div class="palms">🌴&nbsp;💎&nbsp;🌴</div>
        <div class="tag">How well do you know the Zip?</div>
        <p class="blurb">Ten glam questions on the show, the street, and the Pink Palace. Beat the clock, stack a streak, and climb from Peach Pit Regular to Rodeo Drive Royalty.</p>
        <div class="row">
          <button class="btn" id="startBtn">Start Quiz</button>
        </div>
        <div class="best-note" id="bestNote"></div>
      </div>
    </section>

    <!-- ===== QUIZ ===== -->
    <section class="screen" id="scr-quiz">
      <div class="head">
        <div class="brand">
          <span class="mark">🌴</span>
          <div>
            <div class="zip">90210 Trivia</div>
            <div class="sub">Beverly Hills</div>
          </div>
        </div>
        <div class="hud">
          <div class="pill streak" id="streakPill"><span class="lab">Streak</span><span id="streakVal">🔥0</span></div>
          <div class="pill"><span class="lab">Score</span><span id="scoreVal">0</span></div>
        </div>
      </div>

      <div class="timer-wrap"><div class="timer-bar" id="timerBar"></div></div>

      <div class="qmeta">Question <b id="qNum">1</b> / <span id="qTot">10</span></div>
      <div class="question" id="questionText">—</div>
      <div class="opts" id="opts"></div>

      <div class="footline">
        <span id="feedback">Tap the answer you think is right.</span>
        <span class="pts" id="ptsGain"></span>
      </div>
    </section>

    <!-- ===== RESULT ===== -->
    <section class="screen" id="scr-result">
      <div class="result">
        <div class="kicker" style="font-size:12px;letter-spacing:.3em;text-transform:uppercase;color:var(--ivory-dk)">Your Verdict</div>
        <div id="newBestWrap"></div>
        <div class="rank" id="rankTitle">—</div>
        <div class="rank-sub" id="rankSub"></div>
        <div class="scorecard">
          <div class="stat"><div class="n" id="rScore">0</div><div class="l">Score</div></div>
          <div class="stat"><div class="n" id="rAcc">0%</div><div class="l">Accuracy</div></div>
          <div class="stat"><div class="n" id="rStreak">0</div><div class="l">Best Streak</div></div>
        </div>
        <div class="row" style="display:flex;gap:10px;justify-content:center;flex-wrap:wrap">
          <button class="btn" id="againBtn">Play Again</button>
          <button class="btn ghost" id="shareBtn">Share Score</button>
        </div>
        <div class="best-note" id="shareNote"></div>
      </div>
    </section>

  </div>
</div>

<script>
(function(){
  "use strict";

  // ---------- Question bank (every answer verified) ----------
  // correct: index into the ORIGINAL a[] array (options are shuffled at render).
  var BANK = [
    { q:"Which zip code is famously synonymous with Beverly Hills glamour?",
      a:["90210","90211","90209","90212"], correct:0 },
    { q:'The teen drama "Beverly Hills, 90210" originally aired on which network?',
      a:["Fox","NBC","ABC","CBS"], correct:0 },
    { q:"What was the name of the gang's favorite diner hangout on the show?",
      a:["The Peach Pit","The Max","Arnold's","The Bronze"], correct:0 },
    { q:"Which street is the global symbol of Beverly Hills luxury shopping?",
      a:["Rodeo Drive","Melrose Avenue","Sunset Boulevard","Mulholland Drive"], correct:0 },
    { q:"Twins Brandon and Brenda Walsh moved to Beverly Hills from which state?",
      a:["Minnesota","Ohio","Kansas","Michigan"], correct:0 },
    { q:"Who played the brooding bad boy Dylan McKay?",
      a:["Luke Perry","Jason Priestley","Ian Ziering","Brian Austin Green"], correct:0 },
    { q:"What was the name of the high school the characters attended?",
      a:["West Beverly Hills High","Bayside High","Sunnydale High","Rydell High"], correct:0 },
    { q:'The mega-producer behind "Beverly Hills, 90210" was?',
      a:["Aaron Spelling","Dick Wolf","Norman Lear","J.J. Abrams"], correct:0 },
    { q:"Which actress played Donna Martin — and is the producer's daughter?",
      a:["Tori Spelling","Jennie Garth","Shannen Doherty","Gabrielle Carteris"], correct:0 },
    { q:'The famous pink "Beverly Hills Hotel" is nicknamed the?',
      a:["Pink Palace","Flamingo","Rose House","Peninsula"], correct:0 },
    { q:'"Pretty Woman" (1990) famously filmed at which Beverly Hills hotel?',
      a:["The Beverly Wilshire","Chateau Marmont","The Roosevelt","Hotel Bel-Air"], correct:0 },
    { q:"The city of Beverly Hills is bordered largely by which bigger city?",
      a:["Los Angeles","Santa Monica","Culver City","Burbank"], correct:0 },
    { q:"Ian Ziering played which wisecracking, well-off character?",
      a:["Steve Sanders","David Silver","Brandon Walsh","Dylan McKay"], correct:0 },
    { q:"David Silver, who becomes a DJ, was played by?",
      a:["Brian Austin Green","Jason Priestley","Luke Perry","Ian Ziering"], correct:0 },
    { q:"The 2008 reboot of the franchise was titled simply?",
      a:['"90210"',"Melrose Place","The O.C.","One Tree Hill"], correct:0 },
    { q:"Which sister show was a 90210 spinoff set in an L.A. apartment complex?",
      a:["Melrose Place","Dawson's Creek","Party of Five","The O.C."], correct:0 },
    { q:"Kelly Taylor was portrayed by which actress?",
      a:["Jennie Garth","Shannen Doherty","Tori Spelling","Tiffani Thiessen"], correct:0 },
    { q:"Brenda Walsh was played by?",
      a:["Shannen Doherty","Jennie Garth","Tori Spelling","Tiffani Thiessen"], correct:0 },
    { q:"Rodeo Drive sits in which U.S. state?",
      a:["California","New York","Florida","Nevada"], correct:0 },
    { q:"Which trees line the boulevards and are iconic to Beverly Hills?",
      a:["Palm trees","Oak trees","Redwoods","Cherry blossoms"], correct:0 },
    { q:"Jason Priestley played which straight-arrow Walsh twin?",
      a:["Brandon Walsh","Steve Sanders","Dylan McKay","David Silver"], correct:0 },
    { q:"Gabrielle Carteris played the studious newspaper editor?",
      a:["Andrea Zuckerman","Kelly Taylor","Donna Martin","Brenda Walsh"], correct:0 },
    { q:"What was the name of the kindly Peach Pit owner?",
      a:["Nat","Sal","Arthur","Mel"], correct:0 },
    { q:"Tiffani-Amber Thiessen joined the show as which character?",
      a:["Valerie Malone","Kelly Taylor","Clare Arnold","Gina Kincaid"], correct:0 },
    { q:"Beverly Hills, Bel-Air and Holmby Hills together form which nickname?",
      a:["The Platinum Triangle","The Golden Mile","The Diamond District","The Sunset Strip"], correct:0 },
    { q:"The Beverly Hills Hotel first opened in which year — before the city itself?",
      a:["1912","1935","1955","1901"], correct:0 },
    { q:"Beverly Hills was incorporated as a city in which year?",
      a:["1914","1888","1932","1969"], correct:0 },
    { q:"The chic shopping district anchored by Rodeo Drive is known as the?",
      a:["Golden Triangle","Miracle Mile","Diamond District","Sunset Strip"], correct:0 },
    { q:"The legendary Polo Lounge is located inside which hotel?",
      a:["The Beverly Hills Hotel","The Beverly Wilshire","Chateau Marmont","The Peninsula"], correct:0 },
    { q:"After graduation, many characters attended which (fictional) college?",
      a:["California University","Pacific State","West Beverly U","U.C. Sunnydale"], correct:0 },
    { q:'Which 90210 star headlined the "Sharknado" film series?',
      a:["Ian Ziering","Jason Priestley","Luke Perry","Brian Austin Green"], correct:0 },
    { q:"Luke Perry later played Fred Andrews on which CW hit?",
      a:["Riverdale","Gossip Girl","The O.C.","Dawson's Creek"], correct:0 },
    { q:"Shannen Doherty starred as Prue Halliwell on which supernatural series?",
      a:["Charmed","Buffy the Vampire Slayer","Angel","Supernatural"], correct:0 },
    { q:'In "Beverly Hills Cop," Eddie Murphy plays a Detroit cop named?',
      a:["Axel Foley","John McClane","Martin Riggs","Frank Drebin"], correct:0 },
    { q:"Which 1995 comedy follows Beverly Hills teen Cher Horowitz?",
      a:["Clueless","Mean Girls","Legally Blonde","Bring It On"], correct:0 }
  ];

  var ROUND = 10;         // questions per game
  var TIME = 12;          // seconds per question
  var BASE = 100;         // base points for a correct answer
  var LS_BEST = "trivia90210.best";

  // ---------- State ----------
  var deck = [], idx = 0, score = 0, streak = 0, bestStreak = 0, correctCount = 0;
  var timer = null, timeLeft = TIME, locked = false, curCorrectIdx = -1, tickStart = 0;

  // ---------- Elements ----------
  var $ = function(id){ return document.getElementById(id); };
  var scr = { start:$("scr-start"), quiz:$("scr-quiz"), result:$("scr-result") };

  function show(name){
    Object.keys(scr).forEach(function(k){ scr[k].classList.toggle("on", k===name); });
  }

  function shuffle(arr){
    var a = arr.slice();
    for(var i=a.length-1;i>0;i--){ var j=Math.floor(Math.random()*(i+1)); var t=a[i];a[i]=a[j];a[j]=t; }
    return a;
  }

  function bestScore(){ var v = parseInt(localStorage.getItem(LS_BEST)||"0",10); return isNaN(v)?0:v; }

  function refreshBestNote(){
    var b = bestScore();
    $("bestNote").textContent = b>0 ? ("👑  Your best score: " + b) : "";
  }

  // ---------- Game flow ----------
  function startGame(){
    deck = shuffle(BANK).slice(0, ROUND);
    idx = 0; score = 0; streak = 0; bestStreak = 0; correctCount = 0;
    $("qTot").textContent = deck.length;
    $("scoreVal").textContent = "0";
    updateStreak();
    show("quiz");
    renderQuestion();
  }

  function renderQuestion(){
    locked = false;
    var item = deck[idx];
    $("qNum").textContent = (idx+1);
    $("questionText").textContent = item.q;
    $("feedback").textContent = "Tap the answer you think is right.";
    $("ptsGain").textContent = "";

    // Shuffle options, remember where the correct one landed.
    var order = shuffle(item.a.map(function(_,i){ return i; }));
    curCorrectIdx = order.indexOf(item.correct);

    var host = $("opts");
    host.innerHTML = "";
    var keys = ["A","B","C","D"];
    order.forEach(function(origIndex, pos){
      var btn = document.createElement("button");
      btn.className = "opt";
      btn.type = "button";
      btn.dataset.pos = pos;
      btn.innerHTML = '<span class="key">'+keys[pos]+'</span>' +
                      '<span class="txt"></span>' +
                      '<span class="verdict"></span>';
      btn.querySelector(".txt").textContent = item.a[origIndex];
      btn.addEventListener("click", function(){ answer(pos); });
      host.appendChild(btn);
    });

    startTimer();
  }

  function startTimer(){
    timeLeft = TIME; tickStart = Date.now();
    setBar(1, false);
    clearInterval(timer);
    timer = setInterval(function(){
      var elapsed = (Date.now()-tickStart)/1000;
      var frac = Math.max(0, 1 - elapsed/TIME);
      timeLeft = TIME*frac;
      setBar(frac, frac < 0.3);
      if(frac<=0){ clearInterval(timer); timeUp(); }
    }, 80);
  }

  function setBar(frac, warn){
    var bar = $("timerBar");
    bar.style.transform = "scaleX(" + frac + ")";
    bar.classList.toggle("warn", !!warn);
  }

  function answer(pos){
    if(locked) return;
    locked = true;
    clearInterval(timer);
    var elapsed = (Date.now()-tickStart)/1000;
    var opts = Array.prototype.slice.call(document.querySelectorAll(".opt"));
    opts.forEach(function(o){ o.classList.add("locked"); });

    var right = (pos === curCorrectIdx);
    var correctEl = opts[curCorrectIdx];
    correctEl.classList.add("correct");
    correctEl.querySelector(".verdict").textContent = "✓";

    if(right){
      correctCount++;
      streak++;
      if(streak>bestStreak) bestStreak = streak;
      // Points: base + speed bonus (up to +80) + streak multiplier.
      var speed = Math.round(80 * Math.max(0, 1 - elapsed/TIME));
      var mult = 1 + Math.max(0, streak-1) * 0.25;   // 1x,1.25x,1.5x...
      var gain = Math.round((BASE + speed) * mult);
      score += gain;
      $("scoreVal").textContent = score;
      $("ptsGain").textContent = "+" + gain + (streak>1 ? "  ("+mult.toFixed(2)+"×)" : "");
      $("feedback").textContent = streak>=3 ? ("🔥 On fire — "+streak+" in a row!") : "Correct!";
    } else {
      streak = 0;
      opts[pos].classList.add("wrong");
      opts[pos].querySelector(".verdict").textContent = "✕";
      opts.forEach(function(o,i){ if(i!==pos && i!==curCorrectIdx) o.classList.add("dim"); });
      $("feedback").textContent = "Not quite — streak reset.";
      $("ptsGain").textContent = "";
    }
    updateStreak();
    setTimeout(nextQuestion, right ? 950 : 1500);
  }

  function timeUp(){
    if(locked) return;
    locked = true;
    var opts = Array.prototype.slice.call(document.querySelectorAll(".opt"));
    opts.forEach(function(o,i){
      o.classList.add("locked");
      if(i===curCorrectIdx){ o.classList.add("correct"); o.querySelector(".verdict").textContent="✓"; }
      else o.classList.add("dim");
    });
    streak = 0; updateStreak();
    $("feedback").textContent = "⏰ Out of time — streak reset.";
    setTimeout(nextQuestion, 1500);
  }

  function nextQuestion(){
    idx++;
    if(idx >= deck.length) finish();
    else renderQuestion();
  }

  function updateStreak(){
    $("streakVal").textContent = "🔥" + streak;
    $("streakPill").classList.toggle("hot", streak>=3);
  }

  // ---------- Result ----------
  function rankFor(pct, sc){
    if(pct>=100) return { t:"Rodeo Drive Royalty", s:"Flawless — the Zip bows to you" };
    if(pct>=80)  return { t:"Beverly Hills A-Lister", s:"Valet's got your Bentley out front" };
    if(pct>=60)  return { t:"Pink Palace Regular", s:"Poolside with the in-crowd" };
    if(pct>=40)  return { t:"Peach Pit Local", s:"A booth's always waiting for you" };
    if(pct>=20)  return { t:"West Bev Freshman", s:"New in town — keep studying" };
    return { t:"Tourist on Rodeo", s:"Just window shopping for now" };
  }

  function finish(){
    clearInterval(timer);
    var pct = Math.round(100 * correctCount / deck.length);
    var rk = rankFor(pct, score);
    $("rankTitle").textContent = rk.t;
    $("rankSub").textContent = rk.s;
    $("rScore").textContent = score;
    $("rAcc").textContent = pct + "%";
    $("rStreak").textContent = bestStreak;

    var prevBest = bestScore();
    if(score > prevBest){
      localStorage.setItem(LS_BEST, String(score));
      $("newBestWrap").innerHTML = '<span class="new-best">✨ New Personal Best</span>';
    } else {
      $("newBestWrap").innerHTML = "";
    }
    $("shareNote").textContent = "";
    show("result");
  }

  // ---------- Share ----------
  function share(){
    var pct = Math.round(100 * correctCount / deck.length);
    var rk = rankFor(pct, score);
    var text = "I scored " + score + " on 90210 Trivia — " + rk.t + " (" + pct + "% right). Can you beat the Zip? 🌴💎";
    var url = "https://90210.agentabrams.com/#trivia-90210";
    if(navigator.share){
      navigator.share({ title:"90210 Trivia", text:text, url:url }).catch(function(){});
    } else if(navigator.clipboard && navigator.clipboard.writeText){
      navigator.clipboard.writeText(text + " " + url).then(function(){ $("shareNote").textContent = "📋 Score + link copied — paste it anywhere."; })
        .catch(function(){ $("shareNote").textContent = text + " " + url; });
    } else {
      $("shareNote").textContent = text + " " + url;
    }
  }

  // ---------- Wire up ----------
  $("startBtn").addEventListener("click", startGame);
  $("againBtn").addEventListener("click", startGame);
  $("shareBtn").addEventListener("click", share);

  // Keyboard: 1-4 / A-D to answer, Enter to start/replay.
  document.addEventListener("keydown", function(e){
    if(scr.quiz.classList.contains("on") && !locked){
      var map = { "1":0,"2":1,"3":2,"4":3,"a":0,"b":1,"c":2,"d":3 };
      var k = e.key.toLowerCase();
      if(map[k]!=null){ var el=document.querySelector('.opt[data-pos="'+map[k]+'"]'); if(el){ e.preventDefault(); el.click(); } }
    } else if(e.key==="Enter"){
      if(scr.start.classList.contains("on")) startGame();
      else if(scr.result.classList.contains("on")) startGame();
    }
  });

  refreshBestNote();

  // Test/automation hook (mirrors the hub's other games exposing a window handle).
  window.__trivia = {
    start:startGame,
    answerCorrect:function(){ if(!locked){ var el=document.querySelector('.opt[data-pos="'+curCorrectIdx+'"]'); if(el) el.click(); } },
    state:function(){ return { screen:(scr.quiz.classList.contains("on")?"quiz":scr.result.classList.contains("on")?"result":"start"), idx:idx, total:deck.length, score:score, streak:streak, correct:correctCount, locked:locked }; }
  };
})();
</script>
</body>
</html>