-
Details
-
Written by: akadmin
-
Category: Uncategorised
-
-
Hits: 9
{}
@import url('https://fonts.googleapis.com/css2?family=Cinzel:wght@400;700;900&family=Inter:wght@300;400;500;600&family=JetBrains+Mono:wght@400;500&display=swap');
#holy-grail-game * { margin: 0; padding: 0; box-sizing: border-box; }
#holy-grail-game {
font-family: 'Inter', sans-serif;
background: linear-gradient(145deg, #1a1510 0%, #0d0b08 40%, #1a1510 100%);
color: #e0d6c2;
max-width: 500px;
margin: 0 auto;
padding: 24px 20px;
min-height: 100vh;
position: relative;
overflow: hidden;
}
#holy-grail-game::before {
content: '';
position: absolute;
top: 0; left: 0; right: 0;
height: 3px;
background: linear-gradient(90deg, transparent, #d4af37, transparent);
}
/* ---------- SCREENS ---------- */
.grail-screen { display: none; }
.grail-screen.active { display: flex; flex-direction: column; align-items: center; }
/* ---------- INTRO SCREEN ---------- */
.grail-ornament {
font-size: 14px;
letter-spacing: 12px;
color: #d4af37;
opacity: 0.5;
margin: 4px 0;
}
.grail-title {
font-family: 'Cinzel', serif;
font-weight: 900;
font-size: 32px;
letter-spacing: 4px;
text-transform: uppercase;
background: linear-gradient(180deg, #f5e6a3 0%, #d4af37 40%, #a8872a 70%, #d4af37 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
text-align: center;
line-height: 1.1;
margin: 16px 0 4px;
}
.grail-subtitle {
font-family: 'Inter', sans-serif;
font-size: 11px;
font-weight: 300;
letter-spacing: 4px;
text-transform: uppercase;
color: #8a7d6b;
margin-bottom: 24px;
}
.grail-description {
font-size: 13px;
line-height: 1.6;
color: #b0a68e;
text-align: center;
max-width: 380px;
margin-bottom: 24px;
}
.grail-rules {
background: rgba(212, 175, 55, 0.06);
border: 1px solid rgba(212, 175, 55, 0.15);
border-radius: 4px;
padding: 14px 16px;
margin-bottom: 24px;
width: 100%;
max-width: 400px;
}
.grail-rules h3 {
font-family: 'Cinzel', serif;
font-size: 12px;
color: #d4af37;
letter-spacing: 2px;
text-transform: uppercase;
margin-bottom: 8px;
}
.grail-rules ul {
list-style: none;
padding: 0;
}
.grail-rules li {
font-size: 11.5px;
color: #b0a68e;
padding: 3px 0;
padding-left: 16px;
position: relative;
}
.grail-rules li::before {
content: '◆';
position: absolute;
left: 0;
color: #d4af37;
opacity: 0.4;
font-size: 8px;
top: 5px;
}
/* ---------- BUTTONS ---------- */
.grail-btn {
font-family: 'Cinzel', serif;
font-weight: 700;
font-size: 14px;
letter-spacing: 3px;
text-transform: uppercase;
color: #1a1510;
background: linear-gradient(180deg, #f5e6a3, #d4af37, #a8872a);
border: none;
padding: 14px 40px;
cursor: pointer;
transition: all 0.2s ease;
width: 100%;
max-width: 300px;
}
.grail-btn:hover {
filter: brightness(1.15);
transform: translateY(-1px);
}
.grail-btn:active {
transform: translateY(1px);
filter: brightness(0.95);
}
.grail-btn-secondary {
background: transparent;
color: #d4af37;
border: 1px solid rgba(212, 175, 55, 0.3);
font-size: 12px;
padding: 10px 24px;
margin-top: 10px;
}
.grail-btn-secondary:hover {
background: rgba(212, 175, 55, 0.1);
border-color: rgba(212, 175, 55, 0.5);
}
/* ---------- QUESTION SCREEN ---------- */
.grail-progress {
display: flex;
gap: 8px;
margin-bottom: 20px;
justify-content: center;
}
.grail-progress-dot {
width: 12px;
height: 12px;
border-radius: 50%;
border: 1px solid rgba(212, 175, 55, 0.3);
transition: all 0.3s ease;
}
.grail-progress-dot.pass { background: #d4af37; border-color: #d4af37; }
.grail-progress-dot.fail { background: #8b2020; border-color: #8b2020; }
.grail-progress-dot.current { border-color: #d4af37; animation: pulse 1.5s infinite; }
@keyframes pulse {
0%, 100% { box-shadow: 0 0 0 0 rgba(212, 175, 55, 0.4); }
50% { box-shadow: 0 0 0 6px rgba(212, 175, 55, 0); }
}
.grail-difficulty {
font-family: 'JetBrains Mono', monospace;
font-size: 10px;
letter-spacing: 2px;
text-transform: uppercase;
color: #8a7d6b;
margin-bottom: 8px;
}
.grail-question-number {
font-family: 'Cinzel', serif;
font-size: 11px;
color: #d4af37;
letter-spacing: 2px;
text-transform: uppercase;
margin-bottom: 16px;
}
.grail-question-text {
font-size: 16px;
line-height: 1.5;
color: #e0d6c2;
text-align: center;
margin-bottom: 24px;
min-height: 60px;
display: flex;
align-items: center;
justify-content: center;
}
.grail-answers {
display: flex;
flex-direction: column;
gap: 10px;
width: 100%;
max-width: 400px;
}
.grail-answer-btn {
font-family: 'Inter', sans-serif;
font-size: 13px;
font-weight: 400;
color: #c8bda6;
background: rgba(212, 175, 55, 0.06);
border: 1px solid rgba(212, 175, 55, 0.15);
padding: 12px 16px;
cursor: pointer;
transition: all 0.2s ease;
text-align: left;
border-radius: 3px;
}
.grail-answer-btn:hover {
background: rgba(212, 175, 55, 0.12);
border-color: rgba(212, 175, 55, 0.35);
color: #e0d6c2;
}
.grail-answer-btn:active {
transform: scale(0.98);
}
.grail-answer-btn.correct {
background: rgba(46, 125, 50, 0.3);
border-color: #4caf50;
color: #a5d6a7;
}
.grail-answer-btn.wrong {
background: rgba(139, 32, 32, 0.3);
border-color: #8b2020;
color: #ef9a9a;
}
.grail-answer-btn:disabled {
cursor: default;
opacity: 0.6;
}
/* ---------- RESULT SCREEN ---------- */
.grail-result-icon {
font-size: 48px;
margin-bottom: 8px;
}
.grail-result-title {
font-family: 'Cinzel', serif;
font-weight: 900;
font-size: 24px;
letter-spacing: 3px;
text-transform: uppercase;
margin-bottom: 8px;
}
.grail-result-title.pass {
background: linear-gradient(180deg, #f5e6a3, #d4af37);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.grail-result-title.fail {
color: #c0392b;
-webkit-text-fill-color: #c0392b;
}
.grail-result-description {
font-size: 13px;
color: #b0a68e;
text-align: center;
margin-bottom: 16px;
line-height: 1.5;
}
.grail-drink-command {
background: rgba(139, 32, 32, 0.2);
border: 1px solid rgba(192, 57, 43, 0.4);
border-radius: 4px;
padding: 16px;
text-align: center;
margin-bottom: 20px;
width: 100%;
max-width: 350px;
}
.grail-drink-command .drink-label {
font-family: 'JetBrains Mono', monospace;
font-size: 10px;
letter-spacing: 2px;
text-transform: uppercase;
color: #8a7d6b;
margin-bottom: 6px;
}
.grail-drink-command .drink-text {
font-family: 'Cinzel', serif;
font-size: 20px;
font-weight: 700;
color: #ef5350;
letter-spacing: 2px;
}
.grail-drink-command .drink-sub {
font-size: 12px;
color: #b0a68e;
margin-top: 4px;
}
.grail-safe-text {
font-family: 'Cinzel', serif;
font-size: 18px;
color: #d4af37;
text-align: center;
margin-bottom: 20px;
letter-spacing: 2px;
}
/* ---------- DRINK COUNTER ---------- */
.grail-drink-counter {
position: fixed;
top: 12px;
right: 12px;
background: rgba(26, 21, 16, 0.95);
border: 1px solid rgba(212, 175, 55, 0.2);
border-radius: 4px;
padding: 8px 12px;
z-index: 100;
display: none;
}
.grail-drink-counter.visible { display: block; }
.grail-drink-counter .counter-label {
font-family: 'JetBrains Mono', monospace;
font-size: 9px;
letter-spacing: 1px;
text-transform: uppercase;
color: #8a7d6b;
}
.grail-drink-counter .counter-value {
font-family: 'Cinzel', serif;
font-size: 18px;
color: #d4af37;
text-align: center;
}
.grail-drink-counter .counter-sub {
font-size: 9px;
color: #6b6255;
text-align: center;
}
/* ---------- END SCREEN ---------- */
.grail-rank-badge {
font-family: 'Cinzel', serif;
font-size: 28px;
font-weight: 900;
letter-spacing: 4px;
text-transform: uppercase;
background: linear-gradient(180deg, #f5e6a3 0%, #d4af37 40%, #a8872a 70%, #d4af37 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
margin: 12px 0;
}
.grail-stats {
background: rgba(212, 175, 55, 0.06);
border: 1px solid rgba(212, 175, 55, 0.15);
border-radius: 4px;
padding: 14px 16px;
margin: 16px 0;
width: 100%;
max-width: 350px;
}
.grail-stats-row {
display: flex;
justify-content: space-between;
padding: 4px 0;
border-bottom: 1px solid rgba(212, 175, 55, 0.08);
}
.grail-stats-row:last-child { border-bottom: none; }
.grail-stats-label {
font-size: 11px;
color: #8a7d6b;
text-transform: uppercase;
letter-spacing: 1px;
}
.grail-stats-value {
font-family: 'JetBrains Mono', monospace;
font-size: 12px;
color: #d4af37;
}
.grail-quote {
font-style: italic;
font-size: 12px;
color: #6b6255;
text-align: center;
margin: 16px 0;
line-height: 1.5;
}
/* ---------- LOADING ---------- */
.grail-loading {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 200px;
}
.grail-loading .spinner {
width: 32px;
height: 32px;
border: 3px solid rgba(212, 175, 55, 0.2);
border-top-color: #d4af37;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
.grail-loading p {
margin-top: 12px;
font-size: 12px;
color: #8a7d6b;
letter-spacing: 2px;
text-transform: uppercase;
}
Drinks
0
0 sips · 0 finishes
◆ ◇ ◆
The Bridge
of Death
Holy Grail Trials · Trial I
Three questions stand between you and the Grail.
Answer wisely, or drink from the cup of consequence.
Rules
Answer 3 questions of increasing difficulty
Pass 2 or more: The Grail spares you
Fail 2 or more: Drink from the Grail
Critical fail (0 correct): Finish your glass
Cross the Bridge
Easy
Question 1 of 3
Loading...
Answer A
Answer B
Answer C
Answer D
⚔️
Correct
The Grail smiles upon you.
Drink from the Grail
SIP
Take a sip of the Holy Grail
The Grail spares you
Next Question
◆ ◇ ◆
Trial Complete
The Bridge of Death
Grail Knight
"You have crossed the bridge wisely."
Questions Passed
0
Questions Failed
0
Total Drinks
0
Sips
0
Finishes
0
Play Again
Return to Bridge
Consulting the Grail...
var HolyGrail = {
gameId: null,
currentQuestion: 0,
totalQuestions: 3,
questions: [],
correctIndex: null,
results: [],
totalDrinks: 0,
totalSips: 0,
totalFinishes: 0,
trialsPassed: 0,
trialsFailed: 0,
difficulties: ['easy', 'medium', 'hard'],
ajaxUrl: '/ajax-game.php',
// ---------- SCREEN MANAGEMENT ----------
showScreen: function(screenId) {
var screens = document.querySelectorAll('#holy-grail-game .grail-screen');
for (var i = 0; i < screens.length; i++) {
screens[i].classList.remove('active');
}
document.getElementById(screenId).classList.add('active');
},
showLoading: function() {
this.showScreen('screen-loading');
},
showIntro: function() {
document.getElementById('drink-counter').classList.remove('visible');
this.showScreen('screen-intro');
},
// ---------- GAME FLOW ----------
startGame: function() {
var self = this;
self.currentQuestion = 0;
self.results = [];
self.totalDrinks = 0;
self.totalSips = 0;
self.totalFinishes = 0;
self.trialsPassed = 0;
self.trialsFailed = 0;
self.questions = [];
self.showLoading();
// Create game in database
self.ajax('new_game', {}, function(response) {
if (response.success) {
self.gameId = response.data.game_id;
document.getElementById('drink-counter').classList.add('visible');
self.updateDrinkCounter();
self.loadQuestion();
} else {
alert('Error starting game: ' + response.message);
self.showIntro();
}
});
},
loadQuestion: function() {
var self = this;
var difficulty = self.difficulties[self.currentQuestion];
self.showLoading();
self.ajax('get_question', { difficulty: difficulty }, function(response) {
if (response.success) {
self.questions[self.currentQuestion] = response.data;
self.correctIndex = response.data.correct_index;
self.showQuestion();
} else {
alert('Error loading question: ' + response.message);
self.showIntro();
}
});
},
showQuestion: function() {
var q = this.questions[this.currentQuestion];
// Update progress dots
for (var i = 0; i < 3; i++) {
var dot = document.getElementById('dot-' + (i + 1));
dot.className = 'grail-progress-dot';
if (i < this.currentQuestion) {
dot.classList.add(this.results[i] ? 'pass' : 'fail');
} else if (i === this.currentQuestion) {
dot.classList.add('current');
}
}
// Update question text
document.getElementById('difficulty-label').textContent = this.difficulties[this.currentQuestion].toUpperCase();
document.getElementById('question-number').textContent = 'Question ' + (this.currentQuestion + 1) + ' of ' + this.totalQuestions;
document.getElementById('question-text').textContent = q.question;
// Update answer buttons
var container = document.getElementById('answers-container');
var buttons = container.querySelectorAll('.grail-answer-btn');
for (var i = 0; i < buttons.length; i++) {
buttons[i].textContent = q.answers[i];
buttons[i].className = 'grail-answer-btn';
buttons[i].disabled = false;
buttons[i].setAttribute('data-index', i);
}
this.showScreen('screen-question');
},
submitAnswer: function(answerIndex) {
var self = this;
var isCorrect = (answerIndex === self.correctIndex);
// Disable all buttons and highlight correct/wrong
var buttons = document.querySelectorAll('#answers-container .grail-answer-btn');
for (var i = 0; i < buttons.length; i++) {
buttons[i].disabled = true;
if (i === self.correctIndex) {
buttons[i].classList.add('correct');
}
if (i === answerIndex && !isCorrect) {
buttons[i].classList.add('wrong');
}
}
// Determine drink tier
var drinkTier = 'none';
var drinksOwed = 0;
if (!isCorrect) {
// Will determine final drink tier at end based on total score
drinkTier = 'sip';
drinksOwed = 1;
}
// Save result
self.results[self.currentQuestion] = isCorrect;
if (isCorrect) {
self.trialsPassed++;
} else {
self.trialsFailed++;
self.totalDrinks++;
self.totalSips++;
}
// Save to database
var responseData = JSON.stringify({
question_id: self.questions[self.currentQuestion].id,
selected: answerIndex,
correct: self.correctIndex
});
self.ajax('save_trial', {
game_id: self.gameId,
trial_number: self.currentQuestion + 1,
trial_type: 'trivia',
passed: isCorrect ? 1 : 0,
drink_tier: drinkTier,
response_data: responseData
}, function(response) {
// Show result after brief delay
setTimeout(function() {
self.showResult(isCorrect);
}, 800);
});
},
showResult: function(isCorrect) {
var self = this;
if (isCorrect) {
document.getElementById('result-icon').textContent = '⚔️';
document.getElementById('result-title').textContent = 'Correct';
document.getElementById('result-title').className = 'grail-result-title pass';
document.getElementById('result-description').textContent = 'The Grail smiles upon you.';
document.getElementById('result-drink').style.display = 'none';
document.getElementById('result-safe').style.display = 'block';
} else {
document.getElementById('result-icon').textContent = '💀';
document.getElementById('result-title').textContent = 'Wrong';
document.getElementById('result-title').className = 'grail-result-title fail';
document.getElementById('result-description').textContent = 'The bridge demands its toll.';
document.getElementById('result-drink').style.display = 'block';
document.getElementById('result-safe').style.display = 'none';
document.getElementById('drink-tier').textContent = 'SIP';
document.getElementById('drink-sub').textContent = 'Take a sip of the Holy Grail';
}
// Update next button text
var nextBtn = document.getElementById('result-next-btn');
if (self.currentQuestion < self.totalQuestions - 1) {
nextBtn.textContent = 'NEXT QUESTION';
} else {
nextBtn.textContent = 'SEE YOUR FATE';
}
self.showScreen('screen-result');
},
nextQuestion: function() {
this.currentQuestion++;
if (this.currentQuestion >= this.totalQuestions) {
this.endGame();
} else {
this.loadQuestion();
}
},
endGame: function() {
var self = this;
// Determine final drink penalty based on total score
var passCount = self.results.filter(function(r) { return r; }).length;
// Critical fail: 0 correct = finish your glass
if (passCount === 0) {
self.totalFinishes++;
self.totalDrinks += 2; // finish = 3 sips worth, already counted 1 per fail
}
// Determine rank
var rank, quote;
if (passCount === 3) {
rank = 'Grail Knight';
quote = '"You have crossed the bridge wisely."';
} else if (passCount === 2) {
rank = 'Seeker';
quote = '"The Grail tests you, but you prevail."';
} else if (passCount === 1) {
rank = 'Fallen Crusader';
quote = '"You stumbled, but the bridge remains."';
} else {
rank = 'Grail Wretch';
quote = '"The bridge has claimed you entirely."';
}
// End game in database
self.ajax('end_game', { game_id: self.gameId }, function(response) {
// Update stats display
document.getElementById('rank-title').textContent = rank;
document.getElementById('rank-quote').textContent = quote;
document.getElementById('stat-passed').textContent = self.trialsPassed;
document.getElementById('stat-failed').textContent = self.trialsFailed;
document.getElementById('stat-drinks').textContent = self.totalDrinks;
document.getElementById('stat-sips').textContent = self.totalSips;
document.getElementById('stat-finishes').textContent = self.totalFinishes;
self.showScreen('screen-end');
});
},
updateDrinkCounter: function() {
document.getElementById('drink-count').textContent = this.totalDrinks;
document.getElementById('drink-detail').textContent = this.totalSips + ' sips · ' + this.totalFinishes + ' finishes';
},
// ---------- AJAX HELPER ----------
ajax: function(action, data, callback) {
var params = 'action=' + encodeURIComponent(action);
for (var key in data) {
if (data.hasOwnProperty(key)) {
params += '&' + encodeURIComponent(key) + '=' + encodeURIComponent(data[key]);
}
}
var xhr = new XMLHttpRequest();
xhr.open('POST', this.ajaxUrl, true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onload = function() {
if (xhr.status === 200) {
try {
var response = JSON.parse(xhr.responseText);
callback(response);
} catch (e) {
callback({ success: false, message: 'Parse error' });
}
} else {
callback({ success: false, message: 'Server error: ' + xhr.status });
}
};
xhr.onerror = function() {
callback({ success: false, message: 'Network error' });
};
xhr.send(params);
}
};
{}