feat: add logo and logo-inspired color theme
All checks were successful
Dev / test (push) Successful in 4m55s
Dev / docker (push) Successful in 2m9s

- Add transparent SVG logo to img/
- Serve img/ as static files, set SVG favicon
- Show logo on login page and header bar
- Theme Quasar CSS variables using logo palette:
  light: primary #3598C3, secondary #5AA6B9, header navy gradient
  dark: primary #5AA6B9, secondary #3598C3, darker header gradient
This commit is contained in:
Stefano Bertelli 2026-03-31 15:43:21 -05:00
parent f2b04ea668
commit 0c11cddb53
5 changed files with 59 additions and 6 deletions

1
img/wiregui.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 45 KiB

View file

@ -7,6 +7,9 @@ from wiregui.config import get_settings
from wiregui.db import init_db from wiregui.db import init_db
from wiregui.log_config import setup_logging from wiregui.log_config import setup_logging
# Serve static assets (logo, images)
app.add_static_files("/img", "img")
# Mount REST API # Mount REST API
app.include_router(api_router, prefix="/api") app.include_router(api_router, prefix="/api")
@ -89,6 +92,7 @@ def main() -> None:
host=settings.host, host=settings.host,
port=settings.port, port=settings.port,
title="WireGUI", title="WireGUI",
favicon="img/wiregui.svg",
storage_secret=settings.secret_key, storage_secret=settings.secret_key,
reload=True, reload=True,
) )

View file

@ -64,6 +64,7 @@ def layout(title: str = "WireGUI"):
with ui.header().classes("items-center justify-between"): with ui.header().classes("items-center justify-between"):
with ui.row().classes("items-center"): with ui.row().classes("items-center"):
ui.button(icon="menu", on_click=lambda: drawer.toggle()).props("flat color=white") ui.button(icon="menu", on_click=lambda: drawer.toggle()).props("flat color=white")
ui.image("/img/wiregui.svg").classes("w-8 h-8")
ui.label("WireGUI").classes("text-h6") ui.label("WireGUI").classes("text-h6")
with ui.row().classes("items-center"): with ui.row().classes("items-center"):
if role == "admin": if role == "admin":

View file

@ -62,6 +62,7 @@ async def login_page():
ui.navigate.to("/") ui.navigate.to("/")
with ui.column().classes("absolute-center items-center"): with ui.column().classes("absolute-center items-center"):
ui.image("/img/wiregui.svg").classes("w-20 h-20")
ui.label("WireGUI").classes("text-h4 text-bold") ui.label("WireGUI").classes("text-h4 text-bold")
ui.label("Sign in to your account").classes("text-subtitle1 q-mb-md") ui.label("Sign in to your account").classes("text-subtitle1 q-mb-md")

View file

@ -2,19 +2,65 @@
from nicegui import ui from nicegui import ui
# Logo palette
_NAVY = "#0E2747"
_BLUE = "#3598C3"
_TEAL = "#5AA6B9"
_TEAL_LIGHT = "#7AC7D6"
_MID_BLUE = "#325F7B"
def apply_style(): def apply_style():
"""Add Manrope font and global CSS overrides. Call once per page.""" """Add Manrope font, logo-based color theme, and global CSS overrides. Call once per page."""
ui.add_head_html( ui.add_head_html(
'<link rel="preconnect" href="https://fonts.googleapis.com">' '<link rel="preconnect" href="https://fonts.googleapis.com">'
'<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>' '<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>'
'<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@200..800&display=swap" rel="stylesheet">' '<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@200..800&display=swap" rel="stylesheet">'
) )
ui.add_css(""" ui.add_css(f"""
body, input, button, select, textarea { body, input, button, select, textarea {{
font-family: 'Manrope', sans-serif !important; font-family: 'Manrope', sans-serif !important;
} }}
code, .font-mono, .q-table__container .monospace { code, .font-mono, .q-table__container .monospace {{
font-family: 'JetBrains Mono', 'Fira Code', monospace !important; font-family: 'JetBrains Mono', 'Fira Code', monospace !important;
} }}
/* ---- Light theme colors ---- */
:root {{
--q-primary: {_BLUE};
--q-secondary: {_TEAL};
--q-accent: {_TEAL_LIGHT};
--q-dark: {_NAVY};
--q-positive: #21BA45;
--q-negative: #C10015;
--q-info: {_MID_BLUE};
--q-warning: #F2C037;
}}
/* Header bar */
.q-header {{
background: linear-gradient(135deg, {_NAVY} 0%, {_MID_BLUE} 100%) !important;
}}
/* Left drawer */
.q-drawer {{
border-right-color: {_TEAL}33 !important;
}}
/* ---- Dark theme overrides ---- */
body.body--dark {{
--q-primary: {_TEAL};
--q-secondary: {_BLUE};
--q-accent: {_TEAL_LIGHT};
--q-dark: {_NAVY};
--q-info: {_TEAL_LIGHT};
}}
body.body--dark .q-header {{
background: linear-gradient(135deg, {_NAVY} 0%, #1a3a5c 100%) !important;
}}
body.body--dark .q-drawer {{
border-right-color: {_MID_BLUE}44 !important;
}}
""") """)