feat(ui): migrate to Tailwind (compiled) + Flowbite JS; new navbar/layout; Docker CSS build
- Add multi-stage CSS build that compiles Tailwind into app/static/tw.css
- Add Tailwind config with dark tokens (bg/nav/card) and purge globs
- Add assets/input.css (@tailwind base/components/utilities + small utilities)
- Replace Tailwind CDN + REMOVE Flowbite CSS (keep Flowbite JS only)
- New base_tailwind.html (top navbar, responsive container, {%- block scripts -%})
- Port pages to Tailwind look/feel with wider content column:
- index: single-column form + recent results, fullscreen spinner overlay, copy-UUID
- result: sticky jump list, Tailwind tables/badges, Suspicious Scripts/Forms sections
- viewer: Monaco-based code viewer in Tailwind card, actions (copy/wrap/raw)
- ssl_tls macro: rewritten with Tailwind (details/summary for raw JSON)
- Dockerfile: add css-builder stage and copy built tw.css into /app/app/static
- Remove Flowbite stylesheet to avoid overrides; Flowbite JS loaded with defer
BREAKING CHANGE:
Legacy CSS classes/components (.card, .badge, etc.) are replaced by Tailwind utilities.
All templates now expect tw.css to be served from /static.
This commit is contained in:
@@ -1,36 +1,76 @@
|
||||
<!doctype html>
|
||||
{# Base layout using Tailwind + Flowbite, non-destructive #}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>{{ app_name }} {{ app_version }}</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/sanitize.css" />
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}" />
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>{{ app_name }} {{ app_version }}</h1>
|
||||
</header>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>{% block title %}{% endblock %} {{ app_name }} </title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% if messages %}
|
||||
<ul class="flash">
|
||||
{% for category, message in messages %}
|
||||
<li class="{{ category }}">{{ message }}</li>
|
||||
{% endfor %}
|
||||
<!-- # Tailwind CSS # -->
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='tw.css') }}">
|
||||
|
||||
{# Your existing CSS stays; we’ll keep only custom tweaks there. #}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
||||
{% block head %}{% endblock %}
|
||||
</head>
|
||||
|
||||
<body class="bg-bg text-gray-200 min-h-screen flex flex-col">
|
||||
{# Top Navbar (Flowbite collapse) #}
|
||||
<nav class="bg-nav border-b border-gray-800">
|
||||
<div class="max-w-7xl mx-auto px-4 py-3">
|
||||
<div class="flex items-center justify-between">
|
||||
<a href="{{ url_for('main.index') }}" class="text-xl font-bold text-white">
|
||||
SneakyScope
|
||||
</a>
|
||||
|
||||
{# Desktop nav #}
|
||||
<ul class="hidden md:flex items-center space-x-6 text-sm">
|
||||
<li>
|
||||
<a href="{{ url_for('main.index') }}">
|
||||
Home
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
|
||||
<main>
|
||||
{# Mobile toggle #}
|
||||
<button data-collapse-toggle="main-menu" type="button"
|
||||
class="md:hidden inline-flex items-center p-2 rounded hover:bg-gray-700"
|
||||
aria-controls="main-menu" aria-expanded="false">
|
||||
<span class="sr-only">Open main menu</span>
|
||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M4 6h16M4 12h16M4 18h16"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{# Mobile menu #}
|
||||
<div class="hidden md:hidden" id="main-menu">
|
||||
<ul class="mt-2 space-y-1 text-sm">
|
||||
<li>
|
||||
<a href="{{ url_for('main.index') }}">
|
||||
Home
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
{# Page content wrapper #}
|
||||
<main class="flex-1">
|
||||
<div class="max-w-7xl mx-auto p-4 md:p-6">
|
||||
{% block content %}{% endblock %}
|
||||
</main>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<small>{{ app_name }} - A self-hosted URL analysis sandbox - {{ app_version }}</small>
|
||||
</footer>
|
||||
</body>
|
||||
{# Footer #}
|
||||
<footer class="bg-nav border-t border-gray-800 text-center p-4">
|
||||
<p class="text-sm text-gray-400">© {{ current_year }} SneakyScope {{ app_name }} {{ app_version }} - A selfhosted URL sandbox</p>
|
||||
</footer>
|
||||
|
||||
{# Flowbite JS (enables collapse) #}
|
||||
<script src="https://cdn.jsdelivr.net/npm/flowbite@2.5.2/dist/flowbite.min.js"></script>
|
||||
{% block scripts %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
{% block page_js %}
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user