feat(brand): "Letter D (sans)" app icon — favicon + sidebar chip

Implements ``Business/DataTools/app_icons.html`` §03 "Letter D (sans)"
as the canonical app mark.

- New ``src/gui/assets/datatools_icon.svg`` — 64×64 SVG, 14px corner
  radius, ink ground (#1c1917), cream "D" (#fef4ed) in
  Geist 700 / -0.04em tracking. Pure SVG so it renders sharp at
  every favicon size; font stack falls back through Geist →
  system sans where the webfont isn't installed (favicons can't load
  Google Fonts).

- ``_home.py``, ``_Activate.py``, ``99_Close.py``: page_icon now
  resolves the SVG path via ``Path(__file__).parent / "assets" /
  "datatools_icon.svg"`` instead of the broom 🧹 / 🔑 / 🛑
  emojis. Streamlit inlines it as a ``data:image/svg+xml;base64,...``
  link tag so the browser tab + OS app-icon for ``python -m src.gui``
  matches the sidebar chip.

- Sidebar ``.dt-brand-mark`` tightened to match the spec's "Letter D
  (sans)" rendering: ``font-weight: 700`` and
  ``letter-spacing: -0.04em`` (was 600 / -0.02em). The on-screen
  chip is now a scaled-up copy of the OS icon.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-19 01:50:18 +00:00
parent d436e34a45
commit 6c3939d21b
5 changed files with 34 additions and 5 deletions

View File

@@ -171,9 +171,11 @@ def _home_page() -> None:
from src.gui.components._legacy import _run_analysis_on_upload from src.gui.components._legacy import _run_analysis_on_upload
from src.i18n import t from src.i18n import t
from pathlib import Path as _Path
_ICON_PATH = str(_Path(__file__).parent / "assets" / "datatools_icon.svg")
st.set_page_config( st.set_page_config(
page_title=t("home.page_title"), page_title=t("home.page_title"),
page_icon="🧹", page_icon=_ICON_PATH,
layout="wide", layout="wide",
) )
hide_streamlit_chrome() hide_streamlit_chrome()

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
UNALOGIX DataTools app icon. Letter "D" (sans wordmark) on ink ground —
matches Business/DataTools/app_icons.html §03 "Letter D (sans)".
Used as the Streamlit favicon (page_icon) and the sidebar brand chip.
Pure SVG so it renders crisp at every favicon size; cream "D" on
``--ink`` background, font-family stack falls back to system sans
where Geist isn't installed.
-->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64">
<rect width="64" height="64" rx="14" fill="#1c1917"/>
<text x="32" y="48"
text-anchor="middle"
font-family="Geist, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif"
font-weight="700"
font-size="44"
letter-spacing="-1.76"
fill="#fef4ed">D</text>
</svg>

After

Width:  |  Height:  |  Size: 827 B

View File

@@ -201,6 +201,10 @@ body, .stApp {
height: 100%; height: 100%;
flex: 1; flex: 1;
} }
/* "Letter D (sans)" wordmark per Business/DataTools/app_icons.html
§03: 28px ink-filled rounded square, cream "D" in Geist 700 with
-0.04em tracking. Same shape used for the favicon SVG so the chip
in the sidebar reads as a scaled-up copy of the OS app icon. */
.dt-brand-mark { .dt-brand-mark {
width: 28px; width: 28px;
height: 28px; height: 28px;
@@ -211,9 +215,9 @@ body, .stApp {
justify-content: center; justify-content: center;
color: var(--accent-fill); color: var(--accent-fill);
font-family: var(--font-sans); font-family: var(--font-sans);
font-weight: 600; font-weight: 700;
font-size: 16px; font-size: 16px;
letter-spacing: -0.02em; letter-spacing: -0.04em;
line-height: 1; line-height: 1;
flex-shrink: 0; flex-shrink: 0;
} }

View File

@@ -20,9 +20,11 @@ if str(_project_root) not in sys.path:
from src.gui.components import hide_streamlit_chrome, shutdown_app from src.gui.components import hide_streamlit_chrome, shutdown_app
from src.i18n import t from src.i18n import t
from pathlib import Path as _Path
_ICON_PATH = str(_Path(__file__).parent.parent / "assets" / "datatools_icon.svg")
st.set_page_config( st.set_page_config(
page_title=t("close_page.page_title"), page_title=t("close_page.page_title"),
page_icon="🛑", page_icon=_ICON_PATH,
layout="wide", layout="wide",
) )
hide_streamlit_chrome() hide_streamlit_chrome()

View File

@@ -26,9 +26,11 @@ from src.gui.components import (
) )
from src.i18n import t from src.i18n import t
from pathlib import Path as _Path
_ICON_PATH = str(_Path(__file__).parent.parent / "assets" / "datatools_icon.svg")
st.set_page_config( st.set_page_config(
page_title=t("activation.page_title"), page_title=t("activation.page_title"),
page_icon="🔑", page_icon=_ICON_PATH,
layout="wide", layout="wide",
) )