148 lines
6.6 KiB
HTML
148 lines
6.6 KiB
HTML
<!doctype html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
<title>TopTrumps - Dinosaurs</title>
|
|
<!-- Small inline favicon to avoid browser requesting /favicon.ico and spamming 404s -->
|
|
<link rel="icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR4nGNgYAAAAAMAASsJTYQAAAAASUVORK5CYII=">
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
|
|
<script src="https://unpkg.com/htmx.org@1.9.5"></script>
|
|
<style>
|
|
/* Theme variables */
|
|
:root{
|
|
--bg:#ffffff;
|
|
--text:#0a0a0a;
|
|
--muted:#4a4a4a;
|
|
--card-bg:#ffffff;
|
|
--accent:#00d1b2;
|
|
}
|
|
[data-theme="dark"]{
|
|
--bg:#0b0f13;
|
|
--text:#e6eef3;
|
|
--muted:#9aa8b0;
|
|
--card-bg:#0f1620;
|
|
--accent:#79ffd4;
|
|
}
|
|
|
|
body{background:var(--bg); color:var(--text)}
|
|
.app-container{padding:1.5rem}
|
|
.card-item{min-height:140px; background:var(--card-bg); color:var(--text)}
|
|
.highlight-new{animation: highlight 1.6s ease}
|
|
@keyframes highlight{0%{background:lavenderblush}100%{background:transparent}}
|
|
|
|
/* Theme toggle */
|
|
#theme-toggle{margin-left:0.5rem}
|
|
/* Top Trumps card styles */
|
|
.toptrump-card{max-width:320px;border-radius:10px;overflow:hidden;background:var(--card-bg);color:var(--text);box-shadow:0 6px 18px rgba(0,0,0,0.12);border:1px solid rgba(0,0,0,0.06)}
|
|
.toptrump-card .hero-image{height:180px;background-size:cover;background-position:center;position:relative;overflow:hidden}
|
|
/* Hero image: make the dinosaur image larger, cover the banner and remove shadow */
|
|
.toptrump-card .hero-image img.card-hero-img{
|
|
position:absolute;
|
|
left:50%;
|
|
top:50%;
|
|
transform:translate(-50%,-50%);
|
|
/* ensure the image fills the banner while keeping aspect ratio */
|
|
min-width:110%;
|
|
min-height:110%;
|
|
width:auto;
|
|
height:auto;
|
|
object-fit:cover;
|
|
border-radius:6px;
|
|
box-shadow:none;
|
|
}
|
|
/* Background picker thumbnails */
|
|
.background-picker{margin-top:0.5rem}
|
|
.background-picker .bg-options{display:flex;gap:0.5rem;flex-wrap:wrap}
|
|
.background-picker .bg-option{width:64px;height:48px;border:1px solid rgba(0,0,0,0.06);display:flex;align-items:center;justify-content:center;cursor:pointer;background:#fff;color:#222;padding:4px;border-radius:4px}
|
|
.background-picker .bg-option img{max-width:100%;max-height:100%;display:block;border-radius:2px}
|
|
.background-picker .bg-option.selected{outline:2px solid var(--accent);box-shadow:0 2px 6px rgba(0,0,0,0.08)}
|
|
.background-picker .bg-option[role="button"]{font-size:0.8rem;padding:6px 8px}
|
|
/* Bulk edit thumbnails */
|
|
.bulk-thumb{width:48px;height:48px;object-fit:cover;border-radius:6px;border:1px solid rgba(0,0,0,0.06);display:inline-block}
|
|
.bulk-thumb.empty{background:rgba(0,0,0,0.04);width:48px;height:48px;border-radius:6px}
|
|
.toptrump-card .title-band{background:var(--accent);color:#072027;padding:0.6rem 0.75rem;text-align:center;font-weight:700;font-size:1.05rem}
|
|
.toptrump-card .card-body{padding:0.75rem}
|
|
.toptrump-card .stat-row{display:flex;align-items:center;gap:0.75rem;padding:0.25rem 0}
|
|
.toptrump-card .stat-label{width:90px;font-weight:600}
|
|
.toptrump-card .stat-bar{flex:1;height:12px;background:rgba(255,255,255,0.06);border-radius:8px;overflow:hidden}
|
|
.toptrump-card .stat-fill{height:100%;background:linear-gradient(90deg,var(--accent),#ffdd57);}
|
|
.toptrump-card .fact-list{margin-top:0.5rem;padding-left:1rem}
|
|
/* Star rating visuals */
|
|
.star { font-size:0.95rem; display:inline-block; line-height:1; margin-left:2px; }
|
|
.star.full { color:#ffdd57; }
|
|
.star.empty { color:rgba(255,255,255,0.25); }
|
|
.star.half { color:rgba(255,255,255,0.25); position:relative; display:inline-block; }
|
|
.star.half::before { content: '★'; color:#ffdd57; position:absolute; left:0; top:0; width:50%; overflow:hidden; display:inline-block; }
|
|
.stat-value { text-align:right; min-width:6.5rem }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<section class="section">
|
|
<div class="container app-container">
|
|
<div class="level">
|
|
<div class="level-left">
|
|
<h1 class="title">TopTrumps — Dinosaurs</h1>
|
|
</div>
|
|
<div class="level-right">
|
|
<div class="level-item">
|
|
<button id="theme-toggle" class="button is-small" aria-pressed="false">Toggle theme</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="messages"></div>
|
|
{% block content %}{% endblock %}
|
|
<div id="modal-root"></div>
|
|
</div>
|
|
</section>
|
|
</body>
|
|
<script>
|
|
(function(){
|
|
const root = document.documentElement;
|
|
const toggle = document.getElementById('theme-toggle');
|
|
function applyTheme(t){
|
|
if(t==='dark') root.setAttribute('data-theme','dark');
|
|
else root.removeAttribute('data-theme');
|
|
if(toggle) toggle.setAttribute('aria-pressed', t==='dark');
|
|
}
|
|
// initial: localStorage -> prefers-color-scheme -> light
|
|
const stored = localStorage.getItem('toptrumps-theme');
|
|
const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
applyTheme(stored || (prefersDark ? 'dark' : 'light'));
|
|
if(toggle){
|
|
toggle.addEventListener('click', ()=>{
|
|
const current = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light';
|
|
const next = current === 'dark' ? 'light' : 'dark';
|
|
applyTheme(next);
|
|
localStorage.setItem('toptrumps-theme', next);
|
|
});
|
|
}
|
|
})();
|
|
</script>
|
|
<script>
|
|
// Ensure HTMX requests include Django CSRF token (reads from cookie)
|
|
(function(){
|
|
function getCookie(name){
|
|
let cookieValue = null;
|
|
if (document.cookie && document.cookie !== ''){
|
|
const cookies = document.cookie.split(';');
|
|
for (let i=0;i<cookies.length;i++){
|
|
const cookie = cookies[i].trim();
|
|
if (cookie.substring(0, name.length + 1) === (name + '=')){
|
|
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return cookieValue;
|
|
}
|
|
document.body.addEventListener('htmx:configRequest', function(evt){
|
|
const csrftoken = getCookie('csrftoken');
|
|
if (csrftoken){
|
|
evt.detail.headers['X-CSRFToken'] = csrftoken;
|
|
}
|
|
});
|
|
})();
|
|
</script>
|
|
</html>
|