From a14f3582e9aaf2a17809c43250ccc0d0bf575310 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Wed, 17 Jun 2026 15:15:02 +0200 Subject: [PATCH] Frontend: Masonry-Layout + kompaktere Kacheln, media/* in .gitignore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - CSS Grid → CSS Columns (column-count:4) für echtes Masonry-Layout - Karten behalten ihre natürliche Höhe, kein Strecken mehr - Responsive: 3 Spalten @1100px, 2 @750px, 1 @500px - Kacheln kompakter: media-crop 200px→160px, weniger Padding - Hover: translateY(-3px) statt scale (vermeidet Clipping im Masonry) - .gitignore: media/* statt media/uploads/ (alle Medien ignorieren) - import re auf Module-Ebene (war vorher nur lokal in extract_halle) --- .gitignore | 2 +- app.py | 60 +++++++++++++++++++++++++++++------------------------- 2 files changed, 33 insertions(+), 29 deletions(-) diff --git a/.gitignore b/.gitignore index 9ff540a..0769338 100644 --- a/.gitignore +++ b/.gitignore @@ -25,7 +25,7 @@ venv/ *.db-wal # Media (too large, stored on disk) -media/uploads/ +media/* *.log # IDE diff --git a/app.py b/app.py index 81098a7..187773d 100644 --- a/app.py +++ b/app.py @@ -15,6 +15,7 @@ Usage: import json import os +import re import sqlite3 import sys from datetime import datetime @@ -1648,7 +1649,7 @@ def public_frontend(): if mime.startswith("image/"): img_tag = ( '' - '
' + '
' 'Beitragsbild' '
' ) @@ -1750,27 +1751,27 @@ def public_frontend(): .site-header .header-right a { color:#aaa; text-decoration:none; font-size:0.8rem; transition:color 0.2s; } .site-header .header-right a:hover { color:#fff; } - /* Main grid */ - .main-grid { max-width:1200px; margin:1.5rem auto; padding:0 1.5rem; display:grid; grid-template-columns:repeat(auto-fill,minmax(280px,1fr)); gap:1.2rem; } + /* Main grid — masonry (CSS columns) */ + .main-grid { max-width:1300px; margin:1.5rem auto; padding:0 1rem; column-count:4; column-gap:1.2rem; } - /* Card — like SPIEL Essen modules */ - .story-card { background:#fff; border-radius:16px; overflow:hidden; box-shadow:0 6px 28px rgba(0,0,0,0.12),0 2px 6px rgba(0,0,0,0.06); transition:transform 0.3s cubic-bezier(0.25, 0.1, 0.25, 1),box-shadow 0.3s ease; display:flex; flex-direction:column; } - .story-card:hover { transform:scale(1.04); box-shadow:0 20px 48px rgba(0,0,0,0.2),0 6px 16px rgba(0,0,0,0.1); z-index:10; position:relative; } + /* Card — masonry tiles, compact */ + .story-card { background:#fff; border-radius:14px; overflow:hidden; box-shadow:0 4px 18px rgba(0,0,0,0.10),0 1px 4px rgba(0,0,0,0.05); transition:box-shadow 0.25s ease,transform 0.2s ease; display:inline-block; width:100%; margin-bottom:1.2rem; break-inside:avoid; } + .story-card:hover { transform:translateY(-3px); box-shadow:0 8px 32px rgba(0,0,0,0.18),0 3px 10px rgba(0,0,0,0.08); } .story-card img { width:100%; height:100%; object-fit:cover; display:block; } .story-card video { width:100%; height:auto; max-height:600px; object-fit:contain; display:block; background:#000; } .story-card { position:relative; } .story-halle-badge { position:absolute; top:10px; right:10px; background:#20228a; color:#fff; padding:0.25rem 0.65rem; border-radius:5px; font-size:0.78rem; font-weight:700; letter-spacing:0.03em; z-index:5; box-shadow:0 2px 6px rgba(0,0,0,0.3); } .story-ausverkauft-badge { position:absolute; top:10px; left:10px; background:#dc3545; color:#fff; padding:0.3rem 0.7rem; border-radius:5px; font-size:0.78rem; font-weight:700; letter-spacing:0.02em; z-index:5; box-shadow:0 2px 6px rgba(0,0,0,0.3); } - .card-content { padding:0.6rem 1rem 0.8rem; display:flex; flex-direction:column; gap:0.25rem; } - .story-meta { display:flex; align-items:center; gap:0.5rem; flex-wrap:wrap; } - .story-type { font-size:0.85rem; } - .story-author { font-weight:600; color:#20228a; font-size:0.82rem; } - .story-date { color:#999; font-size:0.72rem; margin-left:auto; } - .story-time { font-size:0.75rem; color:#666; font-weight:500; } + .card-content { padding:0.45rem 0.85rem 0.55rem; display:flex; flex-direction:column; gap:0.2rem; } + .story-meta { display:flex; align-items:center; gap:0.4rem; flex-wrap:wrap; } + .story-type { font-size:0.8rem; } + .story-author { font-weight:600; color:#20228a; font-size:0.78rem; } + .story-date { color:#999; font-size:0.7rem; margin-left:auto; } + .story-time { font-size:0.7rem; color:#666; font-weight:500; } .story-time-rel { color:#20228a; font-weight:700; } .story-preview { display:none; } - .text-only .story-preview { display:block; font-size:0.85rem; line-height:1.45; color:#444; } - .text-only .card-content { padding-top:0.5rem; } + .text-only .story-preview { display:block; font-size:0.8rem; line-height:1.4; color:#444; } + .text-only .card-content { padding-top:0.4rem; } /* Frontend filter bar */ .frontend-filter { max-width:1100px; margin:1rem auto 0; padding:0 1.5rem; display:flex; gap:0.4rem; flex-wrap:wrap; align-items:center; } @@ -1809,13 +1810,23 @@ def public_frontend(): .site-footer a { color:#20228a; text-decoration:none; font-weight:600; } .site-footer a:hover { text-decoration:underline; } - /* Responsive */ - @media(max-width:600px) { - .site-header { padding:0.8rem 1rem; } - .main-grid { grid-template-columns:1fr; padding:0 1rem; gap:1rem; } + /* Responsive — masonry column counts */ + @media(max-width:1100px) { + .main-grid { column-count:3; } + } + @media(max-width:750px) { + .main-grid { column-count:2; padding:0 0.7rem; column-gap:0.8rem; } + .story-card { margin-bottom:0.8rem; } + } + @media(max-width:500px) { + .main-grid { column-count:1; padding:0 0.8rem; } + .story-card { margin-bottom:1rem; } + .site-header { padding:0.8rem 1rem; } + .submit-bubble { bottom:1rem; right:5rem; } + .chat-overlay { bottom:5rem; right:0.5rem; width:calc(100vw - 1rem); max-height:60vh; } + .chat-bubble { bottom:1rem; right:1rem; } + .submit-overlay { bottom:5rem; right:0.5rem; width:calc(100vw - 1rem); max-height:65vh; } } - - /* ── Chat Bubble + Overlay ────────────────────────────────── */ .chat-bubble { position:fixed; bottom:1.5rem; right:1.5rem; z-index:9999; width:56px; height:56px; border-radius:50%; background:#20228a; color:#fff; border:none; cursor:pointer; font-size:1.6rem; @@ -1856,10 +1867,6 @@ def public_frontend(): transition:background 0.15s; font-family:inherit; } .chat-footer button:hover { background:#161e6e; } .chat-footer button:disabled { opacity:0.5; cursor:default; } - @media(max-width:600px) { - .chat-overlay { bottom:5rem; right:0.5rem; width:calc(100vw - 1rem); max-height:60vh; } - .chat-bubble { bottom:1rem; right:1rem; } - } /* ── Submit Overlay ────────────────────────────────────────── */ .submit-bubble { position:fixed; bottom:1.5rem; right:5.5rem; z-index:9999; @@ -1898,10 +1905,6 @@ def public_frontend(): .submit-body .submit-btn:disabled { opacity:0.5; cursor:default; } .submit-body .status-msg { text-align:center; font-size:0.8rem; margin-top:0.6rem; min-height:1.2rem; } - @media(max-width:600px) { - .submit-overlay { bottom:5rem; right:0.5rem; width:calc(100vw - 1rem); max-height:65vh; } - .submit-bubble { bottom:1rem; right:5rem; } - } @@ -2200,6 +2203,7 @@ def api_query(): return jsonify({'results': results, 'count': len(results)}) + @app.route('/api/chat', methods=['POST']) def api_chat(): """Chat agent with read-only access to published submissions."""