Untitled

 avatar
unknown
plain_text
10 months ago
16 kB
15
Indexable
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Shofar! Tashlich! High-Ho — Rosh Hashanah Game</title>
<style>
  :root{
    --bg:#f8fafc; --card:#ffffff; --muted:#64748b; --accent:#f59e0b;
    --green:#10b981; --red:#ef4444; --blue:#3b82f6;
  }
  *{box-sizing:border-box;font-family:Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,"Helvetica Neue",Arial;}
  body{margin:0;background:linear-gradient(180deg,#f1f5f9 0%,var(--bg) 100%);color:#0f172a;padding:28px;}
  .wrap{max-width:1000px;margin:0 auto;background:var(--card);border-radius:14px;padding:20px;box-shadow:0 10px 30px rgba(2,6,23,.08);}
  header{display:flex;gap:12px;align-items:center;justify-content:space-between;}
  h1{margin:0;font-size:20px;}
  .meta{font-size:13px;color:var(--muted);text-align:right;}
  .controls{display:flex;gap:8px;flex-wrap:wrap;margin:16px 0;}
  button{border:0;padding:8px 12px;border-radius:8px;background:#eef2ff;cursor:pointer;font-weight:600;}
  .btn-green{background:linear-gradient(90deg,#bbf7d0,#86efac);color:#064e3b;}
  .btn-red{background:linear-gradient(90deg,#fecaca,#fda4af);color:#7f1d1d;}
  .btn-blue{background:linear-gradient(90deg,#bfdbfe,#93c5fd);color:#1e3a8a;}
  .card{background:var(--card);border-radius:12px;padding:16px;margin-bottom:12px;border:1px solid #eef2ff;}
  .q-area{min-height:120px;}
  .prompt {margin-top:12px;padding:12px;border-radius:10px;}
  .prompt.good{background:#ecfdf5;color:#064e3b;}
  .prompt.bad{background:#fff1f2;color:#7f1d1d;}
  .history{max-height:160px;overflow:auto;margin-top:8px;font-size:13px;color:var(--muted);}
  input[type=number]{padding:8px;border-radius:8px;border:1px solid #e6eef8;width:110px;}
  .footer{font-size:13px;color:var(--muted);margin-top:8px;}
  .small{font-size:13px;color:var(--muted);}
  .grid{display:grid;grid-template-columns:1fr 320px;gap:12px;}
  @media (max-width:860px){.grid{grid-template-columns:1fr;}}
  .chip{display:inline-block;background:#f1f5f9;padding:6px 8px;border-radius:999px;font-weight:600;margin-right:6px;font-size:13px;}
  .round-buttons button{background:#f8fafc;}
  .muted{color:var(--muted);}
</style>
</head>
<body>
<div class="wrap" role="application" aria-label="Rosh Hashanah Game">
  <header>
    <div>
      <h1>Shofar! Tashlich! High-Ho — Rosh Hashanah Game</h1>
      <div class="small muted">Two-day quiz-play: learn, laugh, and toss symbolic tashlich tokens.</div>
    </div>
    <div class="meta" id="meta">
      Day: <strong id="dayLabel">1</strong> · Round: <strong id="roundLabel">A</strong><br>
      Score: <strong id="score">0</strong> · Tashlich tokens: <strong id="tokens">3</strong>
    </div>
  </header>

  <div class="controls">
    <button id="toggleDay">Toggle Day</button>
    <div class="round-buttons" style="display:flex;gap:6px;">
      <button data-round="A">Round A</button>
      <button data-round="B">Round B</button>
      <button data-round="C">Round C</button>
      <button data-round="D">Round D</button>
      <button data-round="E">Round E</button>
    </div>
    <div style="margin-left:auto;display:flex;gap:8px;">
      <button id="resetGame" style="background:linear-gradient(90deg,#fff7ed,#ffedd5);">Reset Game</button>
      <button id="nextQ" class="btn-blue">Next Q</button>
    </div>
  </div>

  <div class="grid">
    <main>
      <div class="card">
        <div style="display:flex;justify-content:space-between;align-items:flex-start;gap:12px;">
          <div>
            <div class="chip">Question (<span id="qpts">—</span> pts)</div>
            <div class="q-area" id="questionText" aria-live="polite">Select a round to start.</div>
          </div>
          <div style="min-width:220px;">
            <div style="display:flex;flex-direction:column;gap:8px;">
              <button id="markCorrect" class="btn-green">Mark Correct</button>
              <button id="markWrong" class="btn-red">Mark Wrong</button>
              <button id="showAns" style="background:#eef2ff">Show answer</button>
            </div>
          </div>
        </div>

        <div id="promptContainer" style="margin-top:12px;"></div>

        <details style="margin-top:12px;">
          <summary style="cursor:pointer">Answer / Explanation</summary>
          <div id="answerText" style="margin-top:8px;padding:8px;background:#fbfdff;border-radius:8px;color:var(--muted)"></div>
        </details>
      </div>

      <div class="card">
        <strong>Mini-games & ideas</strong>
        <ul class="small">
          <li>Tashlich Toss — toss tokens into a bucket for bonus points.</li>
          <li>Shofar Imitation — imitate Tekiah / Shevarim / Teruah for points.</li>
          <li>Machzor Read — pick a short excerpt and read dramatically for extra points.</li>
        </ul>
      </div>

      <div class="card">
        <strong>Quick script for the quizmaster</strong>
        <p class="small muted">Read the question; players answer; mark correct/wrong; read the shuffled prompt in a silly voice; hand out tashlich tokens when earned.</p>
      </div>
    </main>

    <aside>
      <div class="card">
        <strong>History</strong>
        <div class="history" id="history"></div>
      </div>

      <div class="card">
        <strong>Game Controls</strong>
        <div style="margin-top:8px;">
          <label class="small muted">Tashlich tokens:</label>
          <div style="display:flex;gap:8px;align-items:center;margin-top:6px;">
            <button id="tokMinus">-</button>
            <div id="tokenVal" style="min-width:50px;text-align:center;font-weight:700;">3</div>
            <button id="tokPlus">+</button>
          </div>

          <div style="margin-top:12px;">
            <label class="small muted">Set score:</label>
            <div style="margin-top:6px;display:flex;gap:8px;align-items:center;">
              <input id="scoreInput" type="number" value="0" min="0" />
              <button id="applyScore">Apply</button>
            </div>
          </div>
        </div>
      </div>

      <div class="card">
        <strong>Prompts</strong>
        <div class="small muted" style="margin-top:6px;">Right answers & playful roasts are randomized from clean lists (no threats).</div>
        <div style="margin-top:8px;">
          <div class="small"><strong>Right:</strong> Good job my cookie · Permission to marry my daughter · If you're cooking I'm eating · Hi Gabriel · Hi Carlos · Whopper... · Hi Ashira · Correct my sunshine · 1+1=2 · Claim an extra tashlich token</div>
          <div class="small" style="margin-top:8px;"><strong>Wrong:</strong> Goodbye Gabriel · Goodbye Carlos · Goodbye Ashira · That was easy bro — you silly goose · WRONG — sorry · Playful roast · Better luck next time · You owe apple & honey</div>
        </div>
      </div>
    </aside>
  </div>

  <div class="footer">Tip: for kids/family remove the roasts and replace with encouraging prompts. Want a printable card deck? Ask and I'll generate one.</div>
</div>

<script>
(() => {
  // Questions deck
  const questions = [
    { q: "Rosh Hashanah signifies what?", a: "The Jewish New Year — a time of reflection and renewal.", pts: 10, day:1, round:"A" },
    { q: "Name one traditional food eaten with honey.", a: "Apple (or challah dipped in honey).", pts: 10, day:1, round:"B" },
    { q: "What is tashlich?", a: "A ritual of symbolically casting away sins by tossing pieces of bread into flowing water.", pts: 15, day:1, round:"B", bonusToken:true },
    { q: "Name the three basic shofar sounds called during Rosh Hashanah services.", a: "Tekiah, Shevarim, Teruah.", pts: 15, day:2, round:"C" },
    { q: "Which Torah story is often read on Rosh Hashanah (the Akedah)?", a: "The Binding of Isaac (Genesis 22).", pts: 20, day:2, round:"C" },
    { q: "What is a machzor?", a: "A special prayerbook for the High Holy Days.", pts: 10, day:2, round:"D" },
    { q: "If Rosh Hashanah starts at sundown on Sept 24 and ends at sunset on Sept 26, how many days does it last?", a: "Two days (from sundown to sundown).", pts: 10, day:2, round:"E" },
  ];

  // Cleaned prompts
  const congrats = [
    "Good job, my cookie.",
    "I give you permission to marry my daughter.",
    "If you are cooking then I am eating.",
    "Hi Gabriel.",
    "Hi Carlos.",
    "Whopper whopper whopper whopper junior double triple whopper.",
    "Hi Ashira.",
    "Correct, my sunshine!",
    "1 + 1 = 2.",
    "Nice — claim an extra tashlich token!"
  ];
  const wrongs = [
    "Goodbye Gabriel.",
    "Goodbye Carlos.",
    "Goodbye Ashira.",
    "That question was easy bro — how did you get it wrong, you silly goose?",
    "WRONG — sorry for being harsh.",
    "You are a disappointment (playful roast).",
    "I would say 'better luck next time' but you haven't got a question right so I've lost all hope in you (roast).",
    "Uh oh — you owe the table an apple & honey for moral support."
  ];

  // UI elements
  const dayLabel = document.getElementById('dayLabel');
  const roundLabel = document.getElementById('roundLabel');
  const scoreEl = document.getElementById('score');
  const tokensEl = document.getElementById('tokens');
  const questionText = document.getElementById('questionText');
  const answerText = document.getElementById('answerText');
  const qpts = document.getElementById('qpts');
  const promptContainer = document.getElementById('promptContainer');
  const historyEl = document.getElementById('history');
  const tokenVal = document.getElementById('tokenVal');

  // Buttons
  const toggleDayBtn = document.getElementById('toggleDay');
  const nextQBtn = document.getElementById('nextQ');
  const markCorrectBtn = document.getElementById('markCorrect');
  const markWrongBtn = document.getElementById('markWrong');
  const showAnsBtn = document.getElementById('showAns');
  const resetBtn = document.getElementById('resetGame');

  const tokMinus = document.getElementById('tokMinus');
  const tokPlus = document.getElementById('tokPlus');
  const scoreInput = document.getElementById('scoreInput');
  const applyScoreBtn = document.getElementById('applyScore');

  // Round buttons
  document.querySelectorAll('.round-buttons button').forEach(btn => {
    btn.addEventListener('click', () => {
      setRound(btn.dataset.round);
    });
  });

  // Game state
  let day = 1;
  let round = 'A';
  let score = 0;
  let tokens = 3;
  let currentIndex = -1;
  let history = [];

  function updateMeta(){
    dayLabel.textContent = day;
    roundLabel.textContent = round;
    scoreEl.textContent = score;
    tokensEl.textContent = tokens;
    tokenVal.textContent = tokens;
    qpts.textContent = (currentQuestion() ? currentQuestion().pts : '—');
  }

  function shufflePick(arr){
    return arr[Math.floor(Math.random()*arr.length)];
  }

  function currentQuestion(){
    if(currentIndex >= 0 && currentIndex < questions.length){
      const q = questions[currentIndex];
      if(q.day === day && q.round === round) return q;
    }
    return null;
  }

  function findFirstIndexFor(dayX, roundX){
    return questions.findIndex(q => q.day === dayX && q.round === roundX);
  }

  function setRound(r){
    round = r;
    roundLabel.textContent = round;
    const idx = findFirstIndexFor(day, round);
    currentIndex = idx >= 0 ? idx : -1;
    renderQuestion();
  }

  function toggleDay(){
    day = (day === 1 ? 2 : 1);
    const idx = findFirstIndexFor(day, round);
    currentIndex = idx >= 0 ? idx : -1;
    renderQuestion();
  }

  function nextQuestion(){
    if(currentIndex < 0){
      // pick first for this day/round
      const idx = findFirstIndexFor(day, round);
      currentIndex = idx >= 0 ? idx : -1;
      renderQuestion();
      return;
    }
    let i = currentIndex + 1;
    while(i < questions.length && (questions[i].day !== day || questions[i].round !== round)) i++;
    if(i >= questions.length){
      // wrap to first for this day/round
      const idx = findFirstIndexFor(day, round);
      currentIndex = idx >= 0 ? idx : -1;
    } else currentIndex = i;
    renderQuestion();
  }

  function markCorrect(){
    const q = currentQuestion();
    if(!q) return;
    score += q.pts || 0;
    if(q.bonusToken) tokens += 1;
    const p = shufflePick(congrats);
    history.push({ q: q.q, correct: true, pts: q.pts, prompt: p});
    renderPrompt(true, p);
    renderHistory();
    updateMeta();
  }

  function markWrong(){
    const q = currentQuestion();
    if(!q) return;
    const p = shufflePick(wrongs);
    history.push({ q: q.q, correct: false, pts: 0, prompt: p});
    renderPrompt(false, p);
    renderHistory();
  }

  function renderPrompt(good, text){
    promptContainer.innerHTML = '';
    const div = document.createElement('div');
    div.className = 'prompt ' + (good ? 'good' : 'bad');
    div.innerHTML = '<strong>' + (good ? 'Congrats!' : 'Oops!') + '</strong><div style="margin-top:8px;">' + escapeHtml(text) + '</div>';
    promptContainer.appendChild(div);
  }

  function renderQuestion(){
    answerText.textContent = '';
    promptContainer.innerHTML = '';
    if(currentQuestion()){
      questionText.textContent = currentQuestion().q;
      answerText.textContent = currentQuestion().a;
    } else {
      questionText.textContent = 'No question for this day/round. Use the Round buttons to select a different round or toggle the day.';
      answerText.textContent = '';
    }
    updateMeta();
  }

  function renderHistory(){
    historyEl.innerHTML = '';
    if(history.length === 0) historyEl.textContent = 'No history yet.';
    else {
      // show most recent first
      history.slice().reverse().forEach(h => {
        const d = document.createElement('div');
        d.style.marginBottom = '8px';
        d.innerHTML = '<div style="font-weight:700;">Q: ' + escapeHtml(h.q) + '</div><div style="font-size:13px;color:#475569;">' + (h.correct ? '+' + h.pts + ' pts' : '0 pts') + ' — <em>' + escapeHtml(h.prompt) + '</em></div>';
        historyEl.appendChild(d);
      });
    }
  }

  function resetGame(){
    day = 1; round = 'A'; score = 0; tokens = 3; currentIndex = findFirstIndexFor(1,'A'); history = [];
    renderQuestion(); renderHistory();
  }

  function escapeHtml(str){
    return String(str).replaceAll('&','&amp;').replaceAll('<','&lt;').replaceAll('>','&gt;').replaceAll('"','&quot;');
  }

  // Event listeners
  toggleDayBtn.addEventListener('click', () => { toggleDay(); });
  nextQBtn.addEventListener('click', () => { nextQuestion(); });
  markCorrectBtn.addEventListener('click', () => { markCorrect(); });
  markWrongBtn.addEventListener('click', () => { markWrong(); });
  showAnsBtn.addEventListener('click', () => {
    const ans = currentQuestion() ? currentQuestion().a : 'No answer.';
    answerText.textContent = ans;
  });
  resetBtn.addEventListener('click', () => { if(confirm('Reset the game?')) resetGame(); });

  tokMinus.addEventListener('click', () => { tokens = Math.max(0, tokens - 1); updateMeta(); });
  tokPlus.addEventListener('click', () => { tokens = tokens + 1; updateMeta(); });

  applyScoreBtn.addEventListener('click', () => { const val = Number(scoreInput.value); if(!Number.isNaN(val)) { score = val; updateMeta(); }});
  document.getElementById('scoreInput').addEventListener('change', () => {
    // keep input in sync with score
    scoreInput.value = score;
  });

  // init
  currentIndex = findFirstIndexFor(day, round);
  renderQuestion();
  renderHistory();
  updateMeta();

})();
</script>
</body>
</html>
Editor is loading...
Leave a Comment