diff --git a/cards/forms.py b/cards/forms.py index 162a772..1b0f64a 100644 --- a/cards/forms.py +++ b/cards/forms.py @@ -8,6 +8,7 @@ class DinosaurForm(forms.ModelForm): fields = [ 'name', 'era', 'diet', 'description', 'image', 'speed', 'weight', 'intelligence', 'height', + 'facts', ] widgets = { 'name': forms.TextInput(attrs={'class': 'input', 'placeholder': 'T. rex'}), @@ -21,6 +22,9 @@ class DinosaurForm(forms.ModelForm): 'height': forms.NumberInput(attrs={'class': 'input', 'min': 0, 'max': 100}), } + # Add facts field widget + widgets['facts'] = forms.Textarea(attrs={'class': 'textarea', 'rows': 3, 'placeholder': 'One fact per line'}) + from .models import BackgroundImage diff --git a/cards/migrations/0003_dinosaur_facts.py b/cards/migrations/0003_dinosaur_facts.py new file mode 100644 index 0000000..c1fcc76 --- /dev/null +++ b/cards/migrations/0003_dinosaur_facts.py @@ -0,0 +1,18 @@ +# Generated by Django 6.0 on 2025-12-04 22:43 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('cards', '0002_backgroundimage'), + ] + + operations = [ + migrations.AddField( + model_name='dinosaur', + name='facts', + field=models.TextField(blank=True, help_text='One fact per line; shown as bullet points on the card'), + ), + ] diff --git a/cards/models.py b/cards/models.py index f63bc37..dada2f0 100644 --- a/cards/models.py +++ b/cards/models.py @@ -25,6 +25,7 @@ class Dinosaur(models.Model): weight = models.PositiveSmallIntegerField(default=50) intelligence = models.PositiveSmallIntegerField(default=50) height = models.PositiveSmallIntegerField(default=50) + facts = models.TextField(blank=True, help_text='One fact per line; shown as bullet points on the card') created_at = models.DateTimeField(auto_now_add=True) @@ -34,6 +35,13 @@ class Dinosaur(models.Model): def __str__(self): return self.name + @property + def facts_list(self): + """Return facts as a list of non-empty lines.""" + if not self.facts: + return [] + return [f.strip() for f in self.facts.splitlines() if f.strip()] + class BackgroundImage(models.Model): """Background images used behind card renders. diff --git a/cards/templates/cards/_card_item.html b/cards/templates/cards/_card_item.html index 2889389..0a458c6 100644 --- a/cards/templates/cards/_card_item.html +++ b/cards/templates/cards/_card_item.html @@ -1,29 +1,30 @@ -
-
-
-

{{ card.name }}

-

Era: {{ card.get_era_display }} β€” Diet: {{ card.get_diet_display }}

+
+
+
+ {% if card.image %} + {{ card.name }} + {% endif %} +
+
{{ card.name }}
+
+
Era: {{ card.get_era_display }} β€” Diet: {{ card.get_diet_display }}
+ {% if card.facts_list %} +
    + {% for fact in card.facts_list|slice:":2" %} +
  • {{ fact }}
  • + {% endfor %} +
+ {% endif %} +
+
Speed
+
Weight
+
Intelligence
+
+
+ + + +
-
-
{{ card.description|linebreaksbr }}
- - - - - - - -
Speed{{ card.speed }}
Weight{{ card.weight }}
Intelligence{{ card.intelligence }}
Height{{ card.height }}
-
- - -
-
- {% if card.image %} -
- {{ card.name }} -
- {% endif %}
diff --git a/cards/templates/cards/_card_preview.html b/cards/templates/cards/_card_preview.html new file mode 100644 index 0000000..39b71bc --- /dev/null +++ b/cards/templates/cards/_card_preview.html @@ -0,0 +1,43 @@ +{# HTMX modal fragment for previewing a card #} +{# HTMX modal fragment for previewing a card in Top Trumps style #} + diff --git a/cards/templates/cards/_form.html b/cards/templates/cards/_form.html index 42bf772..1ce735b 100644 --- a/cards/templates/cards/_form.html +++ b/cards/templates/cards/_form.html @@ -38,16 +38,56 @@
+
+ +
+ {{ form.facts }} +

One fact per line β€” will be shown as bullet points on the card.

+
+
+
+
diff --git a/cards/templates/cards/base.html b/cards/templates/cards/base.html index 5b1586f..c136402 100644 --- a/cards/templates/cards/base.html +++ b/cards/templates/cards/base.html @@ -31,6 +31,16 @@ /* 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} + .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} @@ -48,6 +58,7 @@
{% block content %}{% endblock %} +
diff --git a/cards/templates/cards/preview.html b/cards/templates/cards/preview.html new file mode 100644 index 0000000..b1c79f8 --- /dev/null +++ b/cards/templates/cards/preview.html @@ -0,0 +1,7 @@ +{% extends 'cards/base.html' %} + +{% block content %} +
+ {% include 'cards/_card_preview.html' %} +
+{% endblock %} diff --git a/cards/urls.py b/cards/urls.py index d07dd92..f91615e 100644 --- a/cards/urls.py +++ b/cards/urls.py @@ -8,6 +8,7 @@ urlpatterns = [ path('create/', views.card_create, name='create'), path('/edit/', views.card_edit, name='edit'), path('/delete/', views.card_delete, name='delete'), + path('preview//', views.preview_card, name='preview'), path('backgrounds/', views.background_list, name='backgrounds'), path('backgrounds/create/', views.background_create, name='background_create'), path('backgrounds//activate/', views.background_activate, name='background_activate'), diff --git a/cards/views.py b/cards/views.py index 7593a80..c859c96 100644 --- a/cards/views.py +++ b/cards/views.py @@ -132,3 +132,12 @@ def background_delete(request, pk): if is_htmx(request): return HttpResponse(status=204) return redirect('cards:backgrounds') + + +def preview_card(request, pk): + """Render a full preview of a card. HTMX loads the modal fragment into #modal-root.""" + card = get_object_or_404(Dinosaur, pk=pk) + background = BackgroundImage.get_active() if BackgroundImage.objects.exists() else None + if is_htmx(request): + return render(request, 'cards/_card_preview.html', {'card': card, 'background': background}) + return render(request, 'cards/preview.html', {'card': card, 'background': background}) diff --git a/db.sqlite3 b/db.sqlite3 index 163ef49..5c26d24 100644 Binary files a/db.sqlite3 and b/db.sqlite3 differ diff --git a/media/backgrounds/Gemini_Generated_Image_16ctpg16ctpg16ct.png b/media/backgrounds/Gemini_Generated_Image_16ctpg16ctpg16ct.png new file mode 100644 index 0000000..58733f9 Binary files /dev/null and b/media/backgrounds/Gemini_Generated_Image_16ctpg16ctpg16ct.png differ diff --git a/media/backgrounds/Gemini_Generated_Image_ibil7libil7libil.png b/media/backgrounds/Gemini_Generated_Image_ibil7libil7libil.png new file mode 100644 index 0000000..4d3eb00 Binary files /dev/null and b/media/backgrounds/Gemini_Generated_Image_ibil7libil7libil.png differ diff --git a/templates/cards/_card_item.html b/templates/cards/_card_item.html index 2889389..0a458c6 100644 --- a/templates/cards/_card_item.html +++ b/templates/cards/_card_item.html @@ -1,29 +1,30 @@ -
-
-
-

{{ card.name }}

-

Era: {{ card.get_era_display }} β€” Diet: {{ card.get_diet_display }}

+
+
+
+ {% if card.image %} + {{ card.name }} + {% endif %} +
+
{{ card.name }}
+
+
Era: {{ card.get_era_display }} β€” Diet: {{ card.get_diet_display }}
+ {% if card.facts_list %} +
    + {% for fact in card.facts_list|slice:":2" %} +
  • {{ fact }}
  • + {% endfor %} +
+ {% endif %} +
+
Speed
+
Weight
+
Intelligence
+
+
+ + + +
-
-
{{ card.description|linebreaksbr }}
- - - - - - - -
Speed{{ card.speed }}
Weight{{ card.weight }}
Intelligence{{ card.intelligence }}
Height{{ card.height }}
-
- - -
-
- {% if card.image %} -
- {{ card.name }} -
- {% endif %}
diff --git a/templates/cards/_form.html b/templates/cards/_form.html index a34e707..3d79e23 100644 --- a/templates/cards/_form.html +++ b/templates/cards/_form.html @@ -37,16 +37,50 @@
+
+ +
+ {{ form.facts }} +

One fact per line β€” will be shown as bullet points on the card.

+
+
+
+
diff --git a/templates/cards/base.html b/templates/cards/base.html index 5b1586f..c136402 100644 --- a/templates/cards/base.html +++ b/templates/cards/base.html @@ -31,6 +31,16 @@ /* 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} + .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} @@ -48,6 +58,7 @@
{% block content %}{% endblock %} +