← back to Model Arena
data/artifacts/1a0dea3a5b8e/qwen3-14b.html
360 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Roast or Toast</title>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: 'Georgia', serif;
}
body {
background: linear-gradient(to bottom, #ffe6e6, #fff);
color: #333;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 2rem;
user-select: none;
overflow-x: hidden;
}
h1 {
font-size: 2rem;
margin-bottom: 0.5rem;
}
.campfire {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
gap: 1rem;
max-width: 1000px;
width: 100%;
}
.toggle-group {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 1rem;
}
.toggle {
padding: 0.5rem 1rem;
background: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
border-radius: 4px;
cursor: pointer;
transition: all 0.3s;
user-select: none;
}
.toggle:focus,
.toggle:hover {
outline: none;
background: #f5c6cb;
color: #721c24;
transform: scale(1.05);
}
.toggle.active {
background: #d4edda;
color: #155724;
border-color: #c3e6cb;
}
.flame {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
min-height: 60px;
margin: 1rem 0;
}
.flame-container {
position: relative;
width: 80px;
height: 80px;
}
.flame-sprite {
position: absolute;
top: 0;
left: 0;
width: 80px;
height: 80px;
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="80" height="80" viewBox="0 0 80 80"><path fill="%23e63900" d="M10,30 C10,10 50,10 50,30 C50,50 10,50 10,30 Z" /></svg>');
transition: transform 0.3s, opacity 0.3s;
transform: rotate(15deg);
}
.flame-sprite.flame-1 {
transform: rotate(15deg) scale(1);
opacity: 1;
}
.flame-sprite.flame-2 {
transform: rotate(-15deg) scale(0.75);
opacity: 0.7;
}
.flame-sprite.flame-3 {
transform: rotate(-15deg) scale(0.5);
opacity: 0.3;
}
.output {
background: #fff8f8;
border: 1px solid #e6dada;
padding: 1rem;
border-radius: 8px;
max-width: 700px;
width: 100%;
overflow-y: auto;
max-height: 200px;
}
.output.loading {
background: #fff0f0;
color: #a0522d;
font-style: italic;
text-align: center;
}
.output.empty {
color: #ccc;
font-style: italic;
text-align: center;
padding: 1rem;
}
.output.error {
background: #ffcccc;
color: #d9534f;
border: 1px solid #e55555;
}
.output.success {
background: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
.button-group {
display: flex;
gap: 0.5rem;
margin-top: 1rem;
}
.button {
padding: 0.5rem 1rem;
background: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
border-radius: 4px;
cursor: pointer;
transition: all 0.2s;
user-select: none;
}
.button:focus,
.button:hover {
outline: none;
background: #f5c6cb;
color: #721c24;
transform: scale(1.05);
}
.button.disabled {
background: #e6e6e6;
color: #999;
cursor: not-allowed;
}
.button.mercy {
background: #d1e7dd;
color: #0f5132;
border-color: #b2dfbd;
}
.button.mercy:focus,
.button.mercy:hover {
background: #c3e6cb;
}
@media (min-width: 768px) {
.toggle-group {
flex-wrap: nowrap;
}
}
@media (max-width: 600px) {
h1 {
font-size: 1.5rem;
}
}
@media (prefers-reduced-motion: no-preference) {
.flame-sprite {
animation: flicker 1s infinite ease-in-out;
}
}
@keyframes flicker {
0% { opacity: 0.8; }
50% { opacity: 1.1; }
100% { opacity: 0.8; }
}
</style>
</head>
<body>
<div class="campfire">
<h1>Roast or Toast</h1>
<div class="toggle-group">
<button class="toggle" aria-pressed="false" aria-label="Toggle to Toast mode">Toast</button>
<button class="toggle" aria-pressed="false" aria-label="Toggle to Roast mode">Roast</button>
</div>
<div class="flame">
<div class="flame-container">
<div class="flame-sprite flame-1" style="animation: flicker 1s infinite ease-in-out;"></div>
<div class="flame-sprite flame-2" style="animation: flicker 1s infinite ease-in-out;"></div>
<div class="flame-sprite flame-3" style="animation: flicker 1s infinite ease-in-out;"></div>
</div>
<span id="heat-level">Heat level: 0</span>
</div>
<div class="output empty" id="output">
<p>Choose a mode and click 'Generate' to start the fire!</p>
</div>
<div class="button-group">
<button class="button" id="generateBtn">Generate</button>
<button class="button mercy" id="mercyBtn" disabled>Mercy</button>
</div>
</div>
<script>
const toggleButtons = document.querySelectorAll('.toggle');
const heatLevel = document.getElementById('heat-level');
const output = document.getElementById('output');
const generateBtn = document.getElementById('generateBtn');
const mercyBtn = document.getElementById('mercyBtn');
const flameSprites = document.querySelectorAll('.flame-sprite');
let mode = 'toast';
let heat = 0;
let isMercyActive = false;
let lastGenerated = '';
toggleButtons.forEach(button => {
button.addEventListener('click', () => {
if (button.getAttribute('aria-pressed') === 'false') {
mode = button.textContent.toLowerCase();
toggleButtons.forEach(btn => btn.setAttribute('aria-pressed', 'false'));
button.setAttribute('aria-pressed', 'true');
button.classList.add('active');
heat = 0;
heatLevel.textContent = 'Heat level: 0';
flameSprites.forEach(sprite => {
sprite.style.animation = 'none';
sprite.offsetHeight; /* trigger reflow */
sprite.style.animation = 'flicker 1s infinite ease-in-out';
});
}
});
});
generateBtn.addEventListener('click', () => {
if (isMercyActive) {
return;
}
generateBtn.disabled = true;
output.classList.remove('empty', 'success', 'error');
output.classList.add('loading');
output.textContent = 'Generating...';
setTimeout(() => {
let content;
const contentData = {
toast: [
'You’re a joy to be around, like a warm hug on a cold morning.',
'Your smile lights up the room better than a thousand candles.',
'You’re the reason I believe in kindness, every single day.',
'You’ve got the heart of a lion and the soul of a poet.',
'You make even the darkest days feel like a beautiful sunset.'
],
roast: [
'You’re so kind, you could probably make a stone cry.',
'You have the attention span of a goldfish on a sugar rush.',
'If you were a vegetable, you’d be a potato—no one really needs you, but somehow you’re still there.',
'You’re the human version of a doorknob—unremarkable but somehow necessary.',
'You’re so optimistic, you might actually believe that clouds are made of cotton candy.'
]
};
let currentContent = contentData[mode];
content = currentContent[Math.floor(Math.random() * currentContent.length)];
if (heat < 5) {
heat += 1;
} else {
heat = 5;
}
heatLevel.textContent = `Heat level: ${heat}`;
flameSprites.forEach((sprite, i) => {
sprite.style.opacity = (5 - heat + i) / 5;
});
output.classList.remove('loading');
output.classList.add('success');
output.innerHTML = `<p>${content}</p>`;
lastGenerated = content;
generateBtn.disabled = false;
mercyBtn.disabled = false;
}, 1000);
});
mercyBtn.addEventListener('click', () => {
isMercyActive = true;
heat = 0;
heatLevel.textContent = 'Heat level: 0';
flameSprites.forEach(sprite => {
sprite.style.opacity = '0';
});
output.classList.remove('success', 'error');
output.classList.add('empty');
output.innerHTML = '<p>Peace restored. The flames have cooled.</p>';
mercyBtn.disabled = true;
generateBtn.disabled = false;
});
window.addEventListener('keydown', (e) => {
if (e.key === 'Enter' && generateBtn.disabled === false) {
generateBtn.click();
}
if (e.key === 'Escape') {
mercyBtn.click();
}
});
// Handle screen resizing for responsiveness
window.addEventListener('resize', () => {
// Re-position flame sprites on resize if needed
});
</script>
</body>
</html>