Files
games/all-games/synchrotron-jeopardy.html
T
2026-06-17 09:13:06 +02:00

573 lines
17 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title>Synchrotron Challenge</title>
<style>
:root {
color-scheme: dark;
--panel: rgba(10, 16, 25, 0.92);
--line: rgba(255, 255, 255, 0.16);
--text: #f8f3ea;
--muted: #aeb8c8;
--cyan: #65d8e8;
--gold: #f2c96b;
--green: #88d76f;
--red: #ef735f;
}
* { box-sizing: border-box; }
html,
body {
height: 100%;
margin: 0;
}
body {
overflow: hidden;
user-select: none;
-webkit-user-select: none;
-webkit-tap-highlight-color: transparent;
background:
radial-gradient(circle at 16% 12%, rgba(101, 216, 232, 0.22), transparent 28%),
radial-gradient(circle at 86% 80%, rgba(242, 201, 107, 0.12), transparent 32%),
linear-gradient(140deg, #101926 0%, #1b242d 48%, #080b10 100%);
color: var(--text);
font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
.shell {
display: grid;
grid-template-rows: auto 1fr auto;
height: 100%;
gap: 12px;
padding: 16px;
}
header,
footer {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
}
.brand {
display: grid;
grid-template-columns: auto 1fr;
align-items: center;
gap: 12px;
}
.brand-logo {
width: clamp(48px, 8vw, 76px);
height: auto;
opacity: 0.58;
}
.brand-text {
display: grid;
gap: 2px;
}
.brand small {
color: var(--cyan);
font-size: 0.78rem;
font-weight: 900;
letter-spacing: 0.08em;
text-transform: uppercase;
}
h1 {
margin: 0;
font-size: clamp(1.45rem, 3.5vw, 2.5rem);
line-height: 1;
}
.scorebar {
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
gap: 8px;
}
.score,
.tip,
button {
border: 1px solid var(--line);
border-radius: 8px;
background: var(--panel);
box-shadow: 0 16px 36px rgba(0, 0, 0, 0.28);
backdrop-filter: blur(12px);
}
.score {
min-width: 112px;
padding: 8px 10px;
}
.score span {
display: block;
color: var(--muted);
font-size: 0.7rem;
font-weight: 900;
text-transform: uppercase;
}
.score strong {
display: block;
margin-top: 2px;
font-size: 1.1rem;
font-variant-numeric: tabular-nums;
}
main {
min-height: 0;
position: relative;
display: grid;
}
.watermark {
position: absolute;
inset: 0;
z-index: 0;
display: grid;
place-items: center;
pointer-events: none;
opacity: 0.05;
transform: rotate(-18deg);
}
.watermark img {
width: min(62vmin, 520px);
height: auto;
}
.board {
min-height: 0;
position: relative;
z-index: 1;
display: grid;
grid-template-columns: repeat(5, minmax(0, 1fr));
grid-template-rows: auto repeat(5, minmax(0, 1fr));
gap: 8px;
}
.category,
.tile {
border: 1px solid var(--line);
border-radius: 8px;
background: rgba(9, 14, 22, 0.88);
box-shadow: 0 18px 42px rgba(0, 0, 0, 0.28);
}
.category {
min-height: 74px;
display: grid;
place-items: center;
padding: 8px;
color: var(--cyan);
font-size: clamp(0.72rem, 1.45vw, 1rem);
font-weight: 900;
text-align: center;
text-transform: uppercase;
}
.tile {
min-height: 72px;
display: grid;
place-items: center;
padding: 8px;
color: var(--gold);
font-size: clamp(1.3rem, 3.4vw, 2.6rem);
font-weight: 1000;
cursor: pointer;
touch-action: manipulation;
}
.tile.used {
color: rgba(255, 255, 255, 0.2);
background: rgba(255, 255, 255, 0.04);
cursor: default;
}
.overlay {
position: fixed;
inset: 0;
z-index: 10;
display: grid;
place-items: center;
padding: 16px;
background: rgba(2, 5, 10, 0.62);
backdrop-filter: blur(8px);
}
.overlay[hidden] {
display: none;
}
.modal {
width: min(900px, 100%);
border: 1px solid var(--line);
border-radius: 8px;
padding: 24px;
background: rgba(7, 11, 18, 0.95);
box-shadow: 0 28px 90px rgba(0, 0, 0, 0.55);
}
.modal-top {
display: flex;
justify-content: space-between;
align-items: start;
gap: 12px;
margin-bottom: 14px;
}
.modal h2 {
margin: 0;
color: var(--cyan);
font-size: clamp(1rem, 2.2vw, 1.25rem);
text-transform: uppercase;
}
.value {
color: var(--gold);
font-size: clamp(1.4rem, 4vw, 2.4rem);
font-weight: 1000;
line-height: 1;
}
.clue {
min-height: 145px;
display: grid;
align-items: center;
margin: 0;
font-size: clamp(1.55rem, 4vw, 3.2rem);
font-weight: 900;
line-height: 1.12;
}
.answer {
margin: 16px 0 0;
border-left: 4px solid var(--gold);
padding: 12px 0 12px 14px;
color: var(--text);
font-size: clamp(1.2rem, 2.6vw, 1.7rem);
font-weight: 800;
}
.answer[hidden] {
display: none;
}
.modal-actions {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-top: 18px;
}
button {
min-height: 40px;
padding: 0 8px;
color: var(--text);
font: inherit;
font-weight: 900;
cursor: pointer;
touch-action: manipulation;
}
.modal-actions button,
footer button {
min-height: 38px;
font-size: 0.88rem;
}
button.primary {
border-color: rgba(242, 201, 107, 0.62);
background: linear-gradient(180deg, #f3d16e, #d89a37);
color: #211609;
}
button.good {
border-color: rgba(136, 215, 111, 0.58);
background: rgba(136, 215, 111, 0.14);
}
button.bad {
border-color: rgba(239, 115, 95, 0.58);
background: rgba(239, 115, 95, 0.14);
}
.tip {
padding: 8px 10px;
color: var(--muted);
font-size: 0.9rem;
}
.footer-actions {
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
gap: 8px;
}
@media (max-width: 820px) {
body {
overflow: auto;
}
.shell {
min-height: 100%;
height: auto;
padding: 10px;
}
header,
footer {
align-items: stretch;
flex-direction: column;
}
.scorebar,
.footer-actions {
justify-content: flex-start;
}
.board {
grid-template-columns: repeat(5, minmax(92px, 1fr));
overflow-x: auto;
padding-bottom: 6px;
}
}
</style>
</head>
<body>
<div class="shell">
<header>
<div class="brand">
<img class="brand-logo" src="assets/txproducts-logo-watermark.png" alt="">
<div class="brand-text">
<small>txproducts.de exhibition quiz</small>
<h1>Synchrotron Challenge</h1>
</div>
</div>
<div class="scorebar">
<div class="score"><span>Score</span><strong id="score">0</strong></div>
<div class="score"><span>Answered</span><strong id="answered">0 / 25</strong></div>
</div>
</header>
<main>
<div class="watermark" aria-hidden="true"><img src="assets/txproducts-logo-watermark.png" alt=""></div>
<section class="board" id="board" aria-label="Synchrotron quiz board"></section>
</main>
<footer>
<div class="tip">Tap a value, discuss the clue, reveal the answer, then mark correct or missed.</div>
<div class="footer-actions">
<button id="resetButton" type="button">Reset board</button>
<button type="button" onclick="window.location.href='index.html'">Back to menu</button>
</div>
</footer>
</div>
<div class="overlay" id="overlay" hidden>
<article class="modal">
<div class="modal-top">
<div>
<h2 id="modalCategory">Category</h2>
<div id="modalDifficulty">Difficulty</div>
</div>
<div class="value" id="modalValue">100</div>
</div>
<p class="clue" id="modalClue"></p>
<div class="answer" id="modalAnswer" hidden></div>
<div class="modal-actions">
<button class="primary" id="showAnswerButton" type="button">Show answer</button>
<button class="good" id="correctButton" type="button" hidden>Correct</button>
<button class="bad" id="missedButton" type="button" hidden>Missed</button>
<button id="closeButton" type="button">Close</button>
</div>
</article>
</div>
<script>
const categories = [
{
title: "Synchrotron Basics",
clues: [
["A large accelerator facility that produces extremely bright x-rays for experiments.", "What is a synchrotron?"],
["These charged particles are accelerated around the storage ring to generate synchrotron radiation.", "What are electrons?"],
["Scientists use synchrotron x-rays because they are bright, tunable, and can probe this tiny scale.", "What is the atomic or nanoscale?"],
["This property of synchrotron light lets researchers choose x-ray energies for specific materials or edges.", "What is tunability?"],
["This repeating time pattern of x-ray bunches is what timing devices can reshape for experiments.", "What is pulse structure?"]
]
},
{
title: "TXProducts",
clues: [
["This product tailors synchrotron pulse structure from nanoseconds to seconds.", "What is WaveGate?"],
["This product cuts x-ray pulses to picosecond duration using photo-acoustic Bragg switching.", "What is PicoSwitch?"],
["WaveGate controls when pulses are allowed through, shaping this aspect of the beam.", "What is temporal structure?"],
["PicoSwitch uses a photo-acoustic effect together with this diffraction condition.", "What is Bragg diffraction?"],
["Together, WaveGate and PicoSwitch help researchers control this dimension of x-ray experiments.", "What is time?"]
]
},
{
title: "TXData",
clues: [
["A data service helps turn raw detector output into this useful form.", "What is actionable insight?"],
["Good experimental data needs metadata, calibration, and this quality check.", "What is validation?"],
["TXData can help researchers compare runs, spot trends, and reduce this costly problem.", "What is wasted beamtime or failed experiments?"],
["When pulse timing, detector output, and sample conditions are linked, the result is better this.", "What is data context or traceability?"],
["A business benefits when scientific data becomes searchable, reusable, and easier to share across this group.", "What is a team or organization?"]
]
},
{
title: "TXServices",
clues: [
["TXServices can support planning, setup, and optimization so teams make better use of this scarce resource.", "What is beamtime?"],
["A service partner can help translate an experimental question into this practical beamline plan.", "What is a measurement strategy?"],
["Training and support reduce the gap between advanced instruments and this day-to-day user need.", "What is usability or confidence?"],
["When equipment, data, and workflow are aligned, customers can move faster from experiment to this.", "What is decision or result?"],
["For a customer, expert service lowers technical risk and protects this project investment.", "What is time, budget, or ROI?"]
]
},
{
title: "Business Value",
clues: [
["Better pulse control can improve experiment quality by reducing unwanted signal known as this.", "What is background or leakage?"],
["Reliable timing tools help customers spend less time troubleshooting and more time getting these.", "What are results?"],
["TXProducts, TXData, and TXServices together can connect hardware, analysis, and this human support layer.", "What is expertise or service?"],
["A business improves when experiments become more repeatable, data becomes clearer, and decisions become this.", "What is faster or more confident?"],
["For industrial or research customers, the combined offering can turn advanced synchrotron access into this advantage.", "What is competitive advantage?"]
]
}
];
const values = [100, 200, 300, 400, 500];
const difficulties = ["Warm-up", "Basic", "Applied", "Technical", "Expert"];
const board = document.querySelector("#board");
const scoreEl = document.querySelector("#score");
const answeredEl = document.querySelector("#answered");
const overlay = document.querySelector("#overlay");
const modalCategory = document.querySelector("#modalCategory");
const modalDifficulty = document.querySelector("#modalDifficulty");
const modalValue = document.querySelector("#modalValue");
const modalClue = document.querySelector("#modalClue");
const modalAnswer = document.querySelector("#modalAnswer");
const showAnswerButton = document.querySelector("#showAnswerButton");
const correctButton = document.querySelector("#correctButton");
const missedButton = document.querySelector("#missedButton");
const closeButton = document.querySelector("#closeButton");
const resetButton = document.querySelector("#resetButton");
const state = {
score: 0,
answered: 0,
current: null,
used: new Set()
};
function renderBoard() {
board.innerHTML = "";
for (const category of categories) {
const cell = document.createElement("div");
cell.className = "category";
cell.textContent = category.title;
board.appendChild(cell);
}
for (let row = 0; row < values.length; row += 1) {
for (let col = 0; col < categories.length; col += 1) {
const key = `${col}-${row}`;
const tile = document.createElement("button");
tile.className = `tile${state.used.has(key) ? " used" : ""}`;
tile.type = "button";
tile.textContent = state.used.has(key) ? "..." : values[row];
tile.disabled = state.used.has(key);
tile.addEventListener("click", () => openClue(col, row));
tile.addEventListener("touchend", (event) => {
event.preventDefault();
openClue(col, row);
}, { passive: false });
board.appendChild(tile);
}
}
}
function openClue(col, row) {
const key = `${col}-${row}`;
if (state.used.has(key)) return;
const category = categories[col];
const [clue, answer] = category.clues[row];
state.current = { key, value: values[row], clue, answer, category: category.title, difficulty: difficulties[row] };
modalCategory.textContent = category.title;
modalDifficulty.textContent = difficulties[row];
modalValue.textContent = values[row];
modalClue.textContent = clue;
modalAnswer.hidden = true;
modalAnswer.textContent = answer;
showAnswerButton.hidden = false;
correctButton.hidden = true;
missedButton.hidden = true;
overlay.hidden = false;
}
function showAnswer() {
modalAnswer.hidden = false;
showAnswerButton.hidden = true;
correctButton.hidden = false;
missedButton.hidden = false;
}
function scoreCurrent(correct) {
if (!state.current) return;
state.used.add(state.current.key);
state.answered += 1;
if (correct) state.score += state.current.value;
else state.score = Math.max(0, state.score - Math.floor(state.current.value / 2));
closeModal();
updateHud();
renderBoard();
}
function closeModal() {
overlay.hidden = true;
state.current = null;
}
function updateHud() {
scoreEl.textContent = state.score;
answeredEl.textContent = `${state.answered} / 25`;
}
function resetBoard() {
state.score = 0;
state.answered = 0;
state.current = null;
state.used.clear();
updateHud();
renderBoard();
overlay.hidden = true;
}
showAnswerButton.addEventListener("click", showAnswer);
correctButton.addEventListener("click", () => scoreCurrent(true));
missedButton.addEventListener("click", () => scoreCurrent(false));
closeButton.addEventListener("click", closeModal);
resetButton.addEventListener("click", resetBoard);
window.addEventListener("keydown", (event) => {
if (event.key === "Escape") closeModal();
if (event.key.toLowerCase() === "r") resetBoard();
});
renderBoard();
updateHud();
</script>
</body>
</html>