diff --git a/app/app.py b/app/app.py index 0fe2b81..4624c02 100644 --- a/app/app.py +++ b/app/app.py @@ -45,6 +45,13 @@ STATS_GENERATE_CMD = os.environ.get("STATS_GENERATE_CMD", "") _gen_lock = threading.Lock() _gen_state = {"generating": False} +try: + _APP_VERSION = subprocess.check_output( + ["git", "rev-parse", "--short", "HEAD"], stderr=subprocess.DEVNULL, text=True + ).strip() +except Exception: + _APP_VERSION = "—" + _HIDDEN = frozenset({ ".git", "scripts", "app", @@ -361,6 +368,7 @@ def _inject_globals(): "user": u, "trash_count": _trash_count() if u else 0, "humansize": _humansize, + "app_version": _APP_VERSION, } diff --git a/app/static/app.css b/app/static/app.css index 8a5958c..25761b8 100644 --- a/app/static/app.css +++ b/app/static/app.css @@ -11,7 +11,8 @@ } *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } -body { font-family: 'Segoe UI', system-ui, sans-serif; background: var(--bg); color: var(--text); min-height: 100vh; } +body { font-family: 'Segoe UI', system-ui, sans-serif; background: var(--bg); color: var(--text); min-height: 100vh; display: flex; flex-direction: column; } +main { flex: 1; } a { color: var(--blue); text-decoration: none; } a:hover { text-decoration: underline; } code { background: #e8eef7; padding: .1rem .4rem; border-radius: 4px; font-size: .88em; } @@ -261,6 +262,21 @@ main { max-width: 1100px; margin: 2rem auto; padding: 0 1.5rem 3rem; display: fl .stat-box .value { font-size: 1.4rem; } } +/* ── Footer ─────────────────────────────────────────────────────────── */ +footer { background: var(--blue-dark); color: rgba(255,255,255,.6); margin-top: auto; } +.footer-inner { max-width: 1100px; margin: 0 auto; padding: .9rem 1.5rem; + display: flex; align-items: center; gap: 1.5rem; flex-wrap: wrap; } +.footer-brand { display: flex; align-items: center; gap: .45rem; color: rgba(255,255,255,.85); + font-size: .88rem; text-decoration: none; } +.footer-brand img { opacity: .75; border-radius: 3px; } +.footer-brand:hover { color: #fff; text-decoration: none; } +.footer-brand strong { font-weight: 700; } +.footer-nav { display: flex; gap: 1.2rem; flex: 1; } +.footer-nav a { color: rgba(255,255,255,.55); font-size: .82rem; } +.footer-nav a:hover { color: rgba(255,255,255,.9); text-decoration: none; } +.footer-version { margin-left: auto; font-size: .75rem; color: rgba(255,255,255,.35); + font-family: monospace; } + /* ── Corbeille ──────────────────────────────────────────────────────── */ .trash-header { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: .75rem; margin-bottom: .5rem; } .trash-header h2 { margin: 0; font-size: 1.1rem; } diff --git a/app/templates/base.html b/app/templates/base.html index 41769b2..5084d28 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -44,5 +44,20 @@ {% block content %}{% endblock %} + +