This commit is contained in:
Ross
2025-12-06 18:47:08 +00:00
parent f33a7705d1
commit 09922d7019
10 changed files with 294 additions and 3 deletions
@@ -0,0 +1,45 @@
{# Design 1: Classic Top Trumps - clean, balanced layout #}
<div class="modal is-active" id="card-preview-modal">
<div class="modal-background" onclick="document.getElementById('modal-root').innerHTML=''"></div>
<div class="modal-content">
<div style="max-width:920px; margin:0 auto;">
<div style="display:flex; justify-content:center;">
<div class="toptrump-card design-1" style="width:520px; border-radius:8px; overflow:hidden; box-shadow:0 6px 18px rgba(0,0,0,0.12);">
<div style="padding:8px; display:flex; gap:8px; justify-content:flex-end;"></div>
<div class="hero-image" style="background-image: url('{% if card.background and card.background.image %}{{ card.background.image.url }}{% elif background and background.image %}{{ background.image.url }}{% endif %}'); background-size:cover; background-position:center; height:200px;">
{% if card.image %}
<img class="card-hero-img" src="{{ card.image.url }}" alt="{{ card.name }}" style="position:relative; top:50%; left:50%; transform:translate(-50%,-50%) scale({{ card.image_scale }}); max-height:180px;">
{% endif %}
</div>
<div class="title-band" style="background:#2a7ae2; color:white; padding:12px; font-weight:700; font-size:1.2rem; text-align:center">{{ card.name }}</div>
<div class="card-body" style="padding:12px; background:#fff;">
<div class="subtitle is-6"><strong>Era:</strong> {{ card.get_era_display }} — <strong>Diet:</strong> {{ card.get_diet_display }}</div>
<div style="margin-top:0.5rem">{{ card.description|linebreaksbr }}</div>
{% if card.facts_list %}
<div style="margin-top:0.5rem">
<strong>Fun facts</strong>
<ul class="fact-list">
{% for fact in card.facts_list %}
<li>{{ fact }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
<div style="margin-top:0.8rem">
{% include 'cards/_card_stats_rows.html' %}
</div>
</div>
</div>
</div>
</div>
</div>
<div style="position:absolute; top:12px; right:12px; display:flex; gap:8px;">
<a class="button is-medium {% if design == 1 %}is-primary{% else %}is-light{% endif %}" hx-get="{% url 'cards:preview' card.pk %}?design=1" hx-target="#modal-root" hx-swap="innerHTML" aria-label="Design 1">1</a>
<a class="button is-medium {% if design == 2 %}is-primary{% else %}is-light{% endif %}" hx-get="{% url 'cards:preview' card.pk %}?design=2" hx-target="#modal-root" hx-swap="innerHTML" aria-label="Design 2">2</a>
<a class="button is-medium {% if design == 3 %}is-primary{% else %}is-light{% endif %}" hx-get="{% url 'cards:preview' card.pk %}?design=3" hx-target="#modal-root" hx-swap="innerHTML" aria-label="Design 3">3</a>
<a class="button is-medium {% if design == 4 %}is-primary{% else %}is-light{% endif %}" hx-get="{% url 'cards:preview' card.pk %}?design=4" hx-target="#modal-root" hx-swap="innerHTML" aria-label="Design 4">4</a>
<a class="button is-medium {% if design == 5 %}is-primary{% else %}is-light{% endif %}" hx-get="{% url 'cards:preview' card.pk %}?design=5" hx-target="#modal-root" hx-swap="innerHTML" aria-label="Design 5">5</a>
</div>
<button class="modal-close is-large" aria-label="close" onclick="document.getElementById('modal-root').innerHTML=''" style="right:8px;"></button>
</div>
@@ -0,0 +1,44 @@
{# Design 2: Dark, bold band and inverted text #}
<div class="modal is-active" id="card-preview-modal">
<div class="modal-background" onclick="document.getElementById('modal-root').innerHTML=''"></div>
<div class="modal-content">
<div style="max-width:920px; margin:0 auto;">
<div style="display:flex; justify-content:center;">
<div class="toptrump-card design-2" style="width:520px; border-radius:6px; overflow:hidden; background:#111; color:#eee;">
<div class="hero-image" style="background-image: url('{% if card.background and card.background.image %}{{ card.background.image.url }}{% elif background and background.image %}{{ background.image.url }}{% endif %}'); background-size:cover; background-position:center; height:220px; filter:brightness(0.7);">
{% if card.image %}
<img class="card-hero-img" src="{{ card.image.url }}" alt="{{ card.name }}" style="position:relative; top:50%; left:50%; transform:translate(-50%,-50%) scale({{ card.image_scale }}); max-height:200px; border-radius:6px; box-shadow:0 8px 20px rgba(0,0,0,0.6);">
{% endif %}
</div>
<div class="title-band" style="background:#0b2b2b; color:#9fffbf; padding:14px; font-weight:800; font-size:1.3rem; text-align:center">{{ card.name }}</div>
<div class="card-body" style="padding:14px; background:#111; color:#eaeaea;">
<div class="subtitle is-6"><strong>Era:</strong> {{ card.get_era_display }} — <strong>Diet:</strong> {{ card.get_diet_display }}</div>
<div style="margin-top:0.5rem">{{ card.description|linebreaksbr }}</div>
{% if card.facts_list %}
<div style="margin-top:0.5rem">
<strong>Fun facts</strong>
<ul class="fact-list">
{% for fact in card.facts_list %}
<li>{{ fact }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
<div style="margin-top:0.8rem">
{% include 'cards/_card_stats_rows.html' %}
</div>
</div>
</div>
</div>
</div>
</div>
<div style="position:absolute; top:12px; right:12px; display:flex; gap:8px;">
<a class="button is-medium {% if design == 1 %}is-primary{% else %}is-light{% endif %}" hx-get="{% url 'cards:preview' card.pk %}?design=1" hx-target="#modal-root" hx-swap="innerHTML" aria-label="Design 1">1</a>
<a class="button is-medium {% if design == 2 %}is-primary is-link{% else %}is-light{% endif %}" hx-get="{% url 'cards:preview' card.pk %}?design=2" hx-target="#modal-root" hx-swap="innerHTML" aria-label="Design 2">2</a>
<a class="button is-medium {% if design == 3 %}is-primary{% else %}is-light{% endif %}" hx-get="{% url 'cards:preview' card.pk %}?design=3" hx-target="#modal-root" hx-swap="innerHTML" aria-label="Design 3">3</a>
<a class="button is-medium {% if design == 4 %}is-primary{% else %}is-light{% endif %}" hx-get="{% url 'cards:preview' card.pk %}?design=4" hx-target="#modal-root" hx-swap="innerHTML" aria-label="Design 4">4</a>
<a class="button is-medium {% if design == 5 %}is-primary{% else %}is-light{% endif %}" hx-get="{% url 'cards:preview' card.pk %}?design=5" hx-target="#modal-root" hx-swap="innerHTML" aria-label="Design 5">5</a>
</div>
<button class="modal-close is-large" aria-label="close" onclick="document.getElementById('modal-root').innerHTML=''" style="right:8px;"></button>
</div>
@@ -0,0 +1,50 @@
{# Design 3: Bright gradient header and centered stats badges #}
<div class="modal is-active" id="card-preview-modal">
<div class="modal-background" onclick="document.getElementById('modal-root').innerHTML=''"></div>
<div class="modal-content">
<div style="max-width:920px; margin:0 auto;">
<div style="display:flex; justify-content:center;">
<div class="toptrump-card design-3" style="width:520px; border-radius:10px; overflow:hidden; box-shadow:0 10px 30px rgba(0,0,0,0.14);">
<div class="hero-image" style="background-image: linear-gradient(120deg,#ff7a18, #af002d), url('{% if card.background and card.background.image %}{{ card.background.image.url }}{% elif background and background.image %}{{ background.image.url }}{% endif %}'); background-size:cover; background-position:center; height:200px; filter:brightness(0.9);">
{% if card.image %}
<img class="card-hero-img" src="{{ card.image.url }}" alt="{{ card.name }}" style="position:relative; top:50%; left:50%; transform:translate(-50%,-50%) scale({{ card.image_scale }}); max-height:160px; border-radius:8px;">
{% endif %}
</div>
<div class="title-band" style="background:linear-gradient(90deg,#ffd54f,#ff7043); color:#222; padding:12px; font-weight:800; font-size:1.25rem; text-align:center">{{ card.name }}</div>
<div class="card-body" style="padding:12px; background:#fff;">
<div style="display:flex; justify-content:space-between; align-items:center; gap:12px;">
<div><strong>Era:</strong> {{ card.get_era_display }}</div>
<div><strong>Diet:</strong> {{ card.get_diet_display }}</div>
</div>
<div style="margin-top:0.5rem">{{ card.description|linebreaksbr }}</div>
{% if card.facts_list %}
<div style="margin-top:0.5rem">
<strong>Fun facts</strong>
<ul class="fact-list">
{% for fact in card.facts_list %}
<li>{{ fact }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
<div style="margin-top:0.8rem; display:flex; gap:8px; justify-content:space-around;">
<div style="text-align:center"><div style="font-weight:800">{{ card.speed_display }}</div><div class="is-size-7">Speed</div></div>
<div style="text-align:center"><div style="font-weight:800">{{ card.weight_display }}</div><div class="is-size-7">Weight</div></div>
<div style="text-align:center"><div style="font-weight:800">{{ card.intelligence_display }}</div><div class="is-size-7">Intel</div></div>
<div style="text-align:center"><div style="font-weight:800">{{ card.height_display }}</div><div class="is-size-7">Height</div></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div style="position:absolute; top:12px; right:12px; display:flex; gap:8px;">
<a class="button is-medium {% if design == 1 %}is-primary{% else %}is-light{% endif %}" hx-get="{% url 'cards:preview' card.pk %}?design=1" hx-target="#modal-root" hx-swap="innerHTML" aria-label="Design 1">1</a>
<a class="button is-medium {% if design == 2 %}is-primary{% else %}is-light{% endif %}" hx-get="{% url 'cards:preview' card.pk %}?design=2" hx-target="#modal-root" hx-swap="innerHTML" aria-label="Design 2">2</a>
<a class="button is-medium {% if design == 3 %}is-primary is-link{% else %}is-light{% endif %}" hx-get="{% url 'cards:preview' card.pk %}?design=3" hx-target="#modal-root" hx-swap="innerHTML" aria-label="Design 3">3</a>
<a class="button is-medium {% if design == 4 %}is-primary{% else %}is-light{% endif %}" hx-get="{% url 'cards:preview' card.pk %}?design=4" hx-target="#modal-root" hx-swap="innerHTML" aria-label="Design 4">4</a>
<a class="button is-medium {% if design == 5 %}is-primary{% else %}is-light{% endif %}" hx-get="{% url 'cards:preview' card.pk %}?design=5" hx-target="#modal-root" hx-swap="innerHTML" aria-label="Design 5">5</a>
</div>
<button class="modal-close is-large" aria-label="close" onclick="document.getElementById('modal-root').innerHTML=''" style="right:8px;"></button>
</div>
@@ -0,0 +1,50 @@
{# Design 4: Sidebar stats and portrait orientation #}
<div class="modal is-active" id="card-preview-modal">
<div class="modal-background" onclick="document.getElementById('modal-root').innerHTML=''"></div>
<div class="modal-content">
<div style="max-width:920px; margin:0 auto;">
<div style="display:flex; justify-content:center;">
<div class="toptrump-card design-4" style="width:680px; display:flex; gap:12px; border-radius:8px; overflow:hidden; box-shadow:0 8px 24px rgba(0,0,0,0.12);">
<div style="flex:0 0 320px; position:relative; background:#f5f5f5;">
<div class="hero-image" style="background-image: url('{% if card.background and card.background.image %}{{ card.background.image.url }}{% elif background and background.image %}{{ background.image.url }}{% endif %}'); background-size:cover; background-position:center; height:100%; display:flex; align-items:center; justify-content:center;">
{% if card.image %}
<img src="{{ card.image.url }}" alt="{{ card.name }}" style="max-height:420px; transform:scale({{ card.image_scale }});">
{% endif %}
</div>
</div>
<div style="flex:1; padding:14px; background:#fff;">
<div style="display:flex; justify-content:space-between; align-items:center;">
<div style="font-weight:800; font-size:1.4rem">{{ card.name }}</div>
<div class="is-size-7"><strong>{{ card.get_era_display }}</strong></div>
</div>
<div style="margin-top:8px">{{ card.description|linebreaksbr }}</div>
{% if card.facts_list %}
<div style="margin-top:8px">
<strong>Fun facts</strong>
<ul class="fact-list">
{% for fact in card.facts_list %}
<li>{{ fact }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
<div style="margin-top:12px; display:flex; flex-direction:column; gap:10px;">
<div style="display:flex; justify-content:space-between; align-items:center;"><div>Speed</div><div style="font-weight:800">{{ card.speed_display }}</div></div>
<div style="display:flex; justify-content:space-between; align-items:center;"><div>Weight</div><div style="font-weight:800">{{ card.weight_display }}</div></div>
<div style="display:flex; justify-content:space-between; align-items:center;"><div>Intel</div><div style="font-weight:800">{{ card.intelligence_display }}</div></div>
<div style="display:flex; justify-content:space-between; align-items:center;"><div>Height</div><div style="font-weight:800">{{ card.height_display }}</div></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div style="position:absolute; top:12px; right:12px; display:flex; gap:8px;">
<a class="button is-medium {% if design == 1 %}is-primary{% else %}is-light{% endif %}" hx-get="{% url 'cards:preview' card.pk %}?design=1" hx-target="#modal-root" hx-swap="innerHTML" aria-label="Design 1">1</a>
<a class="button is-medium {% if design == 2 %}is-primary{% else %}is-light{% endif %}" hx-get="{% url 'cards:preview' card.pk %}?design=2" hx-target="#modal-root" hx-swap="innerHTML" aria-label="Design 2">2</a>
<a class="button is-medium {% if design == 3 %}is-primary{% else %}is-light{% endif %}" hx-get="{% url 'cards:preview' card.pk %}?design=3" hx-target="#modal-root" hx-swap="innerHTML" aria-label="Design 3">3</a>
<a class="button is-medium {% if design == 4 %}is-primary is-link{% else %}is-light{% endif %}" hx-get="{% url 'cards:preview' card.pk %}?design=4" hx-target="#modal-root" hx-swap="innerHTML" aria-label="Design 4">4</a>
<a class="button is-medium {% if design == 5 %}is-primary{% else %}is-light{% endif %}" hx-get="{% url 'cards:preview' card.pk %}?design=5" hx-target="#modal-root" hx-swap="innerHTML" aria-label="Design 5">5</a>
</div>
<button class="modal-close is-large" aria-label="close" onclick="document.getElementById('modal-root').innerHTML=''" style="right:8px;"></button>
</div>
@@ -0,0 +1,61 @@
{# Design 5: Minimal, high-contrast with icon-like stat rows #}
<div class="modal is-active" id="card-preview-modal">
<div class="modal-background" onclick="document.getElementById('modal-root').innerHTML=''"></div>
<div class="modal-content">
<div style="max-width:920px; margin:0 auto;">
<div style="display:flex; justify-content:center;">
<div class="toptrump-card design-5" style="width:520px; border-radius:6px; overflow:hidden; background:#fff; box-shadow:0 6px 20px rgba(0,0,0,0.08);">
<div style="padding:14px; display:flex; align-items:center; gap:12px;">
<div style="flex:1">
<div style="font-weight:800; font-size:1.3rem">{{ card.name }}</div>
<div class="is-size-7">{{ card.get_era_display }} — {{ card.get_diet_display }}</div>
</div>
{% if card.image %}
<div style="width:120px; height:80px; display:flex; align-items:center; justify-content:center; background:#f0f0f0; border-radius:6px; overflow:hidden;">
<img src="{{ card.image.url }}" alt="{{ card.name }}" style="max-height:76px; transform:scale({{ card.image_scale }});">
</div>
{% endif %}
</div>
<div style="padding:10px 14px; border-top:1px solid #eee;">
<div style="display:flex; gap:8px; justify-content:space-between;">
<div style="flex:1; text-align:center;">
<div style="font-weight:700">{{ card.speed_display }}</div>
<div class="is-size-7">Speed</div>
</div>
<div style="flex:1; text-align:center;">
<div style="font-weight:700">{{ card.weight_display }}</div>
<div class="is-size-7">Weight</div>
</div>
<div style="flex:1; text-align:center;">
<div style="font-weight:700">{{ card.intelligence_display }}</div>
<div class="is-size-7">Intel</div>
</div>
<div style="flex:1; text-align:center;">
<div style="font-weight:700">{{ card.height_display }}</div>
<div class="is-size-7">Height</div>
</div>
</div>
{% if card.facts_list %}
<div style="margin-top:10px;">
<strong>Fun facts</strong>
<ul class="fact-list">
{% for fact in card.facts_list %}
<li>{{ fact }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
<div style="position:absolute; top:12px; right:12px; display:flex; gap:8px;">
<a class="button is-medium {% if design == 1 %}is-primary{% else %}is-light{% endif %}" hx-get="{% url 'cards:preview' card.pk %}?design=1" hx-target="#modal-root" hx-swap="innerHTML" aria-label="Design 1">1</a>
<a class="button is-medium {% if design == 2 %}is-primary{% else %}is-light{% endif %}" hx-get="{% url 'cards:preview' card.pk %}?design=2" hx-target="#modal-root" hx-swap="innerHTML" aria-label="Design 2">2</a>
<a class="button is-medium {% if design == 3 %}is-primary{% else %}is-light{% endif %}" hx-get="{% url 'cards:preview' card.pk %}?design=3" hx-target="#modal-root" hx-swap="innerHTML" aria-label="Design 3">3</a>
<a class="button is-medium {% if design == 4 %}is-primary{% else %}is-light{% endif %}" hx-get="{% url 'cards:preview' card.pk %}?design=4" hx-target="#modal-root" hx-swap="innerHTML" aria-label="Design 4">4</a>
<a class="button is-medium {% if design == 5 %}is-primary is-link{% else %}is-light{% endif %}" hx-get="{% url 'cards:preview' card.pk %}?design=5" hx-target="#modal-root" hx-swap="innerHTML" aria-label="Design 5">5</a>
</div>
<button class="modal-close is-large" aria-label="close" onclick="document.getElementById('modal-root').innerHTML=''" style="right:8px;"></button>
</div>
@@ -0,0 +1,30 @@
<div class="stat-row" style="display:flex; gap:12px; flex-direction:column">
<div style="display:flex; justify-content:space-between; align-items:center">
<div class="stat-label">Speed <small class="is-size-7">(km/h)</small></div>
<div style="text-align:right">
<div style="font-weight:700">{{ card.speed_display }}</div>
<div class="is-size-7" style="font-weight:500; display:flex; align-items:center; gap:8px; justify-content:flex-end;"><div class="stars">{% for t in card.speed_star_types %}<span class="star {{ t }}">{% if t == 'full' %}★{% else %}☆{% endif %}</span>{% endfor %}</div> <span style="margin-left:6px">(orig: {{ card.speed_orig }})</span></div>
</div>
</div>
<div style="display:flex; justify-content:space-between; align-items:center">
<div class="stat-label">Weight <small class="is-size-7">(kg)</small></div>
<div style="text-align:right">
<div style="font-weight:700">{{ card.weight_display }}</div>
<div class="is-size-7" style="font-weight:500; display:flex; align-items:center; gap:8px; justify-content:flex-end;"><div class="stars">{% for t in card.weight_star_types %}<span class="star {{ t }}">{% if t == 'full' %}★{% else %}☆{% endif %}</span>{% endfor %}</div> <span style="margin-left:6px">(orig: {{ card.weight_orig }})</span></div>
</div>
</div>
<div style="display:flex; justify-content:space-between; align-items:center">
<div class="stat-label">Intelligence <small class="is-size-7">(score)</small></div>
<div style="text-align:right">
<div style="font-weight:700">{{ card.intelligence_display }}</div>
<div class="is-size-7" style="font-weight:500; display:flex; align-items:center; gap:8px; justify-content:flex-end;"><div class="stars">{% for t in card.intelligence_star_types %}<span class="star {{ t }}">{% if t == 'full' %}★{% else %}☆{% endif %}</span>{% endfor %}</div> <span style="margin-left:6px">(orig: {{ card.intelligence_orig }})</span></div>
</div>
</div>
<div style="display:flex; justify-content:space-between; align-items:center">
<div class="stat-label">Height <small class="is-size-7">(m)</small></div>
<div style="text-align:right">
<div style="font-weight:700">{{ card.height_display }}</div>
<div class="is-size-7" style="font-weight:500; display:flex; align-items:center; gap:8px; justify-content:flex-end;"><div class="stars">{% for t in card.height_star_types %}<span class="star {{ t }}">{% if t == 'full' %}★{% else %}☆{% endif %}</span>{% endfor %}</div> <span style="margin-left:6px">(orig: {{ card.height_orig }})</span></div>
</div>
</div>
</div>
+1 -1
View File
@@ -2,6 +2,6 @@
{% block content %} {% block content %}
<div class="container"> <div class="container">
{% include 'cards/_card_preview.html' %} {% include fragment_template %}
</div> </div>
{% endblock %} {% endblock %}
+13 -2
View File
@@ -276,9 +276,20 @@ def preview_card(request, pk):
"""Render a full preview of a card. HTMX loads the modal fragment into #modal-root.""" """Render a full preview of a card. HTMX loads the modal fragment into #modal-root."""
card = get_object_or_404(Dinosaur, pk=pk) card = get_object_or_404(Dinosaur, pk=pk)
background = BackgroundImage.get_active() if BackgroundImage.objects.exists() else None background = BackgroundImage.get_active() if BackgroundImage.objects.exists() else None
# Support multiple visual designs selectable via `?design=1..5`.
try:
design = int(request.GET.get('design', '1'))
except Exception:
design = 1
if design < 1 or design > 5:
design = 1
template_name = f'cards/_card_preview_design{design}.html'
template_name = f'cards/_card_preview_design{design}.html'
context = {'card': card, 'background': background, 'design': design, 'fragment_template': template_name}
if is_htmx(request): if is_htmx(request):
return render(request, 'cards/_card_preview.html', {'card': card, 'background': background}) return render(request, template_name, context)
return render(request, 'cards/preview.html', {'card': card, 'background': background}) # For non-HTMX full page preview, render the generic preview which can accept design too
return render(request, 'cards/preview.html', context)
def cards_overview(request): def cards_overview(request):
BIN
View File
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 MiB